Commit Graph

268847 Commits

Author SHA1 Message Date
klensy
590fdfba14 bump opener to sync with rust 2024-10-15 17:51:35 +03:00
Michael Goulet
dca646ab01 Rewrite for<..> async correctly 2024-10-15 10:22:03 -04:00
bors
a0c2aba29a Auto merge of #130654 - lcnr:stabilize-coherence-again, r=compiler-errors
stabilize `-Znext-solver=coherence` again

r? `@compiler-errors`

---

This PR stabilizes the use of the next generation trait solver in coherence checking by enabling `-Znext-solver=coherence` by default. More specifically its use in the *implicit negative overlap check*. The tracking issue for this is https://github.com/rust-lang/rust/issues/114862. Closes #114862.

This is a direct copy of #121848 which has been reverted due to a hang in `nalgebra`: #130056. This hang should have been fixed by #130617 and #130821. See the added section in the stabilization report containing user facing changes merged since the original FCP.

## Background

### The next generation trait solver

The new solver lives in [`rustc_trait_selection::solve`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/solve/mod.rs) and is intended to replace the existing *evaluate*, *fulfill*, and *project* implementation. It also has a wider impact on the rest of the type system, for example by changing our approach to handling associated types.

For a more detailed explanation of the new trait solver, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/solve/trait-solving.html). This does not stabilize the current behavior of the new trait solver, only the behavior impacting the implicit negative overlap check. There are many areas in the new solver which are not yet finalized. We are confident that their final design will not conflict with the user-facing behavior observable via coherence. More on that further down.

Please check out [the chapter](https://rustc-dev-guide.rust-lang.org/solve/significant-changes.html) summarizing the most significant changes between the existing and new implementations.

### Coherence and the implicit negative overlap check

Coherence checking detects any overlapping impls. Overlapping trait impls always error while overlapping inherent impls result in an error if they have methods with the same name. Coherence also results in an error if any other impls could exist, even if they are currently unknown. This affects impls which may get added to upstream crates in a backwards compatible way and impls from downstream crates.

Coherence failing to detect overlap is generally considered to be unsound, even if it is difficult to actually get runtime UB this way. It is quite easy to get ICEs due to bugs in coherence.

It currently consists of two checks:

The [orphan check] validates that impls do not overlap with other impls we do not know about: either because they may be defined in a sibling crate, or because an upstream crate is allowed to add it without being considered a breaking change.

The [overlap check] validates that impls do not overlap with other impls we know about. This is done as follows:
- Instantiate the generic parameters of both impls with inference variables
- Equate the `TraitRef`s of both impls. If it fails there is no overlap.
- [implicit negative]: Check whether any of the instantiated `where`-bounds of one of the impls definitely do not hold when using the constraints from the previous step. If a `where`-bound does not hold, there is no overlap.
- *explicit negative (still unstable, ignored going forward)*: Check whether the any negated `where`-bounds can be proven, e.g. a `&mut u32: Clone` bound definitely does not hold as an explicit `impl<T> !Clone for &mut T` exists.

The overlap check has to *prove that unifying the impls does not succeed*. This means that **incorrectly getting a type error during coherence is unsound** as it would allow impls to overlap: coherence has to be *complete*.

Completeness means that we never incorrectly error. This means that during coherence we must only add inference constraints if they are definitely necessary. During ordinary type checking [this does not hold](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=01d93b592bd9036ac96071cbf1d624a9), so the trait solver has to behave differently, depending on whether we're in coherence or not.

The implicit negative check only considers goals to "definitely not hold" if they could not be implemented downstream, by a sibling, or upstream in a backwards compatible way. If the goal is is "unknowable" as it may get added in another crate, we add an ambiguous candidate: [source](bea5bebf3d/compiler/rustc_trait_selection/src/solve/assembly/mod.rs (L858-L883)).

[orphan check]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L566-L579)
[overlap check]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L92-L98)
[implicit negative]: fd80c02c16/compiler/rustc_trait_selection/src/traits/coherence.rs (L223-L281)

## Motivation

Replacing the existing solver in coherence fixes soundness bugs by removing sources of incompleteness in the type system. The new solver separately strengthens coherence, resulting in more impls being disjoint and passing the coherence check. The concrete changes will be elaborated further down. We believe the stabilization to reduce the likelihood of future bugs in coherence as the new implementation is easier to understand and reason about.

It allows us to remove the support for coherence and implicit-negative reasoning in the old solver, allowing us to remove some code and simplifying the old trait solver. We will only remove the old solver support once this stabilization has reached stable to make sure we're able to quickly revert in case any unexpected issues are detected before then.

Stabilizing the use of the next-generation trait solver expresses our confidence that its current behavior is intended and our work towards enabling its use everywhere will not require any breaking changes to the areas used by coherence checking. We are also confident that we will be able to replace the existing solver everywhere, as maintaining two separate systems adds a significant maintainance burden.

## User-facing impact and reasoning

### Breakage due to improved handling of associated types

The new solver fixes multiple issues related to associated types. As these issues caused coherence to consider more types distinct, fixing them results in more overlap errors. This is therefore a breaking change.

#### Structurally relating aliases containing bound vars

Fixes https://github.com/rust-lang/rust/issues/102048. In the existing solver relating ambiguous projections containing bound variables is structural. This is *incomplete* and allows overlapping impls. These was mostly not exploitable as the same issue also caused impls to not apply when trying to use them. The new solver defers alias-relating to a nested goal, fixing this issue:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Trait {}

trait Project {
    type Assoc<'a>;
}

impl Project for u32 {
    type Assoc<'a> = &'a u32;
}

// Eagerly normalizing `<?infer as Project>::Assoc<'a>` is ambiguous,
// so the old solver ended up structurally relating
//
//     (?infer, for<'a> fn(<?infer as Project>::Assoc<'a>))
//
// with
//
//     ((u32, fn(&'a u32)))
//
// Equating `&'a u32` with `<u32 as Project>::Assoc<'a>` failed, even
// though these types are equal modulo normalization.
impl<T: Project> Trait for (T, for<'a> fn(<T as Project>::Assoc<'a>)) {}

impl<'a> Trait for (u32, fn(&'a u32)) {}
//[next]~^ ERROR conflicting implementations of trait `Trait` for type `(u32, for<'a> fn(&'a u32))`
```

A crater run did not discover any breakage due to this change.

#### Unknowable candidates for higher ranked trait goals

This avoids an unsoundness by attempting to normalize in `trait_ref_is_knowable`, fixing https://github.com/rust-lang/rust/issues/114061. This is a side-effect of supporting lazy normalization, as that forces us to attempt to normalize when checking whether a `TraitRef` is knowable: [source](47dd709bed/compiler/rustc_trait_selection/src/solve/assembly/mod.rs (L754-L764)).

```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait IsUnit {}
impl IsUnit for () {}

pub trait WithAssoc<'a> {
    type Assoc;
}

// We considered `for<'a> <T as WithAssoc<'a>>::Assoc: IsUnit`
// to be knowable, even though the projection is ambiguous.
pub trait Trait {}
impl<T> Trait for T
where
    T: 'static,
    for<'a> T: WithAssoc<'a>,
    for<'a> <T as WithAssoc<'a>>::Assoc: IsUnit,
{
}
impl<T> Trait for Box<T> {}
//[next]~^ ERROR conflicting implementations of trait `Trait`
```
The two impls of `Trait` overlap given the following downstream crate:
```rust
use dep::*;
struct Local;
impl WithAssoc<'_> for Box<Local> {
    type Assoc = ();
}
```

There a similar coherence unsoundness caused by our handling of aliases which is fixed separately in https://github.com/rust-lang/rust/pull/117164.

This change breaks the [`derive-visitor`](https://crates.io/crates/derive-visitor) crate. I have opened an issue in that repo: nikis05/derive-visitor#16.

### Evaluating goals to a fixpoint and applying inference constraints

In the old implementation of the implicit-negative check, each obligation is [checked separately without applying its inference constraints](bea5bebf3d/compiler/rustc_trait_selection/src/traits/coherence.rs (L323-L338)). The new solver instead [uses a `FulfillmentCtxt`](bea5bebf3d/compiler/rustc_trait_selection/src/traits/coherence.rs (L315-L321)) for this, which evaluates all obligations in a loop until there's no further inference progress.

This is necessary for backwards compatibility as we do not eagerly normalize with the new solver, resulting in constraints from normalization to only get applied by evaluating a separate obligation. This also allows more code to compile:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Mirror {
    type Assoc;
}
impl<T> Mirror for T {
    type Assoc = T;
}

trait Foo {}
trait Bar {}

// The self type starts out as `?0` but is constrained to `()`
// due to the where-clause below. Because `(): Bar` is known to
// not hold, we can prove the impls disjoint.
impl<T> Foo for T where (): Mirror<Assoc = T> {}
//[current]~^ ERROR conflicting implementations of trait `Foo` for type `()`
impl<T> Foo for T where T: Bar {}

fn main() {}
```
The old solver does not run nested goals to a fixpoint in evaluation. The new solver does do so, strengthening inference and improving the overlap check:
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait Foo {}
impl<T> Foo for (u8, T, T) {}
trait NotU8 {}
trait Bar {}
impl<T, U: NotU8> Bar for (T, T, U) {}

trait NeedsFixpoint {}
impl<T: Foo + Bar> NeedsFixpoint for T {}
impl NeedsFixpoint for (u8, u8, u8) {}

trait Overlap {}
impl<T: NeedsFixpoint> Overlap for T {}
impl<T, U: NotU8, V> Overlap for (T, U, V) {}
//[current]~^ ERROR conflicting implementations of trait `Foo`
```

### Breakage due to removal of incomplete candidate preference

Fixes #107887. In the old solver we incompletely prefer the builtin trait object impl over user defined impls. This can break inference guidance, inferring `?x` in `dyn Trait<u32>: Trait<?x>` to `u32`, even if an explicit impl of `Trait<u64>` also exists.

This caused coherence to incorrectly allow overlapping impls, resulting in ICEs and a theoretical unsoundness. See https://github.com/rust-lang/rust/issues/107887#issuecomment-1997261676. This compiles on stable but results in an overlap error with `-Znext-solver=coherence`:

```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
struct W<T: ?Sized>(*const T);

trait Trait<T: ?Sized> {
    type Assoc;
}

// This would trigger the check for overlap between automatic and custom impl.
// They actually don't overlap so an impl like this should remain possible
// forever.
//
// impl Trait<u64> for dyn Trait<u32> {}
trait Indirect {}
impl Indirect for dyn Trait<u32, Assoc = ()> {}
impl<T: Indirect + ?Sized> Trait<u64> for T {
    type Assoc = ();
}

// Incomplete impl where `dyn Trait<u32>: Trait<_>` does not hold, but
// `dyn Trait<u32>: Trait<u64>` does.
trait EvaluateHack<U: ?Sized> {}
impl<T: ?Sized, U: ?Sized> EvaluateHack<W<U>> for T
where
    T: Trait<U, Assoc = ()>, // incompletely constrains `_` to `u32`
    U: IsU64,
    T: Trait<U, Assoc = ()>, // incompletely constrains `_` to `u32`
{
}

trait IsU64 {}
impl IsU64 for u64 {}

trait Overlap<U: ?Sized> {
    type Assoc: Default;
}
impl<T: ?Sized + EvaluateHack<W<U>>, U: ?Sized> Overlap<U> for T {
    type Assoc = Box<u32>;
}
impl<U: ?Sized> Overlap<U> for dyn Trait<u32, Assoc = ()> {
//[next]~^ ERROR conflicting implementations of trait `Overlap<_>`
    type Assoc = usize;
}
```

### Considering region outlives bounds in the `leak_check`

For details on the `leak_check`, see the FCP proposal #119820.[^leak_check]

[^leak_check]: which should get moved to the dev-guide :3

In both coherence and during candidate selection, the `leak_check` relies on the region constraints added in `evaluate`. It therefore currently does not register outlives obligations: [source](ccb1415eac/compiler/rustc_trait_selection/src/traits/select/mod.rs (L792-L810)). This was likely done as a performance optimization without considering its impact on the `leak_check`. This is the case as in the old solver, *evaluatation* and *fulfillment* are split, with evaluation being responsible for candidate selection and fulfillment actually registering all the constraints.

This split does not exist with the new solver. The `leak_check` can therefore eagerly detect errors caused by region outlives obligations. This improves both coherence itself and candidate selection:

```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
trait LeakErr<'a, 'b> {}
// Using this impl adds an `'b: 'a` bound which results
// in a higher-ranked region error. This bound has been
// previously ignored but is now considered.
impl<'a, 'b: 'a> LeakErr<'a, 'b> for () {}

trait NoOverlapDir<'a> {}
impl<'a, T: for<'b> LeakErr<'a, 'b>> NoOverlapDir<'a> for T {}
impl<'a> NoOverlapDir<'a> for () {}
//[current]~^ ERROR conflicting implementations of trait `NoOverlapDir<'_>`

// --------------------------------------

// necessary to avoid coherence unknowable candidates
struct W<T>(T);

trait GuidesSelection<'a, U> {}
impl<'a, T: for<'b> LeakErr<'a, 'b>> GuidesSelection<'a, W<u32>> for T {}
impl<'a, T> GuidesSelection<'a, W<u8>> for T {}

trait NotImplementedByU8 {}
trait NoOverlapInd<'a, U> {}
impl<'a, T: GuidesSelection<'a, W<U>>, U> NoOverlapInd<'a, U> for T {}
impl<'a, U: NotImplementedByU8> NoOverlapInd<'a, U> for () {}
//[current]~^ conflicting implementations of trait `NoOverlapInd<'_, _>`
```

### Removal of `fn match_fresh_trait_refs`

The old solver tries to [eagerly detect unbounded recursion](b14fd2359f/compiler/rustc_trait_selection/src/traits/select/mod.rs (L1196-L1211)), forcing the affected goals to be ambiguous. This check is only an approximation and has not been added to the new solver.

The check is not necessary in the new solver and it would be problematic for caching. As it depends on all goals currently on the stack, using a global cache entry would have to always make sure that doing so does not circumvent this check.

This changes some goals to error - or succeed - instead of failing with ambiguity. This allows more code to compile:

```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence

// Need to use this local wrapper for the impls to be fully
// knowable as unknowable candidate result in ambiguity.
struct Local<T>(T);

trait Trait<U> {}
// This impl does not hold, but is ambiguous in the old
// solver due to its overflow approximation.
impl<U> Trait<U> for Local<u32> where Local<u16>: Trait<U> {}
// This impl holds.
impl Trait<Local<()>> for Local<u8> {}

// In the old solver, `Local<?t>: Trait<Local<?u>>` is ambiguous,
// resulting in `Local<?u>: NoImpl`, also being ambiguous.
//
// In the new solver the first impl does not apply, constraining
// `?u` to `Local<()>`, causing `Local<()>: NoImpl` to error.
trait Indirect<T> {}
impl<T, U> Indirect<U> for T
where
    T: Trait<U>,
    U: NoImpl
{}

// Not implemented for `Local<()>`
trait NoImpl {}
impl NoImpl for Local<u8> {}
impl NoImpl for Local<u16> {}

// `Local<?t>: Indirect<Local<?u>>` cannot hold, so
// these impls do not overlap.
trait NoOverlap<U> {}
impl<T: Indirect<U>, U> NoOverlap<U> for T {}
impl<T, U> NoOverlap<Local<U>> for Local<T> {}
//~^ ERROR conflicting implementations of trait `NoOverlap<Local<_>>`
```

### Non-fatal overflow

The old solver immediately emits a fatal error when hitting the recursion limit. The new solver instead returns overflow. This both allows more code to compile and is results in performance and potential future compatability issues.

Non-fatal overflow is generally desirable. With fatal overflow, changing the order in which we evaluate nested goals easily causes breakage if we have goal which errors and one which overflows. It is also required to prevent breakage due to the removal of `fn match_fresh_trait_refs`, e.g. [in `typenum`](https://github.com/rust-lang/trait-system-refactor-initiative/issues/73).

#### Enabling more code to compile

In the below example, the old solver first tried to prove an overflowing goal, resulting in a fatal error. The new solver instead returns ambiguity due to overflow for that goal, causing the implicit negative overlap check to succeed as `Box<u32>: NotImplemented` does not hold.
```rust
// revisions: current next
//[next] compile-flags: -Znext-solver=coherence
//[current] ERROR overflow evaluating the requirement

trait Indirect<T> {}
impl<T: Overflow<()>> Indirect<T> for () {}

trait Overflow<U> {}
impl<T, U> Overflow<U> for Box<T>
where
    U: Indirect<Box<Box<T>>>,
{}

trait NotImplemented {}

trait Trait<U> {}
impl<T, U> Trait<U> for T
where
    // T: NotImplemented, // causes old solver to succeed
    U: Indirect<T>,
    T: NotImplemented,
{}

impl Trait<()> for Box<u32> {}
```

#### Avoiding hangs with non-fatal overflow

Simply returning ambiguity when reaching the recursion limit can very easily result in hangs, e.g.
```rust
trait Recur {}
impl<T, U> Recur for ((T, U), (U, T))
where
    (T, U): Recur,
    (U, T): Recur,
{}

trait NotImplemented {}
impl<T: NotImplemented> Recur for T {}
```
This can happen quite frequently as it's easy to have exponential blowup due to multiple nested goals at each step. As the trait solver is depth-first, this immediately caused a fatal overflow error in the old solver. In the new solver we have to handle the whole proof tree instead, which can very easily hang.

To avoid this we restrict the recursion depth after hitting the recursion limit for the first time. We also **ignore all inference constraints from goals resulting in overflow**. This is mostly backwards compatible as any overflow in the old solver resulted in a fatal error.

### sidenote about normalization

We return ambiguous nested goals of `NormalizesTo` goals to the caller and ignore their impact when computing the `Certainty` of the current goal. See the [normalization chapter](https://rustc-dev-guide.rust-lang.org/solve/normalization.html) for more details.This means we apply constraints resulting from other nested goals and from equating the impl header when normalizing, even if a nested goal results in overflow. This is necessary to avoid breaking the following example:
```rust
trait Trait {
    type Assoc;
}

struct W<T: ?Sized>(*mut T);
impl<T: ?Sized> Trait for W<W<T>>
where
    W<T>: Trait,
{
    type Assoc = ();
}

// `W<?t>: Trait<Assoc = u32>` does not hold as
// `Assoc` gets normalized to `()`. However, proving
// the where-bounds of the impl results in overflow.
//
// For this to continue to compile we must not discard
// constraints from normalizing associated types.
trait NoOverlap {}
impl<T: Trait<Assoc = u32>> NoOverlap for T {}
impl<T: ?Sized> NoOverlap for W<T> {}
```

#### Future compatability concerns

Non-fatal overflow results in some unfortunate future compatability concerns. Changing the approach to avoid more hangs by more strongly penalizing overflow can cause breakage as we either drop constraints or ignore candidates necessary to successfully compile. Weakening the overflow penalities instead allows more code to compile and strengthens inference while potentially causing more code to hang.

While the current approach is not perfect, we believe it to be good enough. We believe it to apply the necessary inference constraints to avoid breakage and expect there to not be any desirable patterns broken by our current penalities. Similarly we believe the current constraints to avoid most accidental hangs. Ignoring constraints of overflowing goals is especially useful, as it may allow major future optimizations to our overflow handling. See [this summary](https://hackmd.io/ATf4hN0NRY-w2LIVgeFsVg) and the linked documents in case you want to know more.

### changes to performance

In general, trait solving during coherence checking is not significant for performance. Enabling the next-generation trait solver in coherence does not impact our compile time benchmarks. We are still unable to compile the benchmark suite when fully enabling the new trait solver.

There are rare cases where the new solver has significantly worse performance due to non-fatal overflow, its reliance on fixpoint algorithms and the removal of the `fn match_fresh_trait_refs` approximation. We encountered such issues in [`typenum`](https://crates.io/crates/typenum) and believe it should be [pretty much as bad as it can get](https://github.com/rust-lang/trait-system-refactor-initiative/issues/73).

Due to an improved structure and far better caching, we believe that there is a lot of room for improvement and that the new solver will outperform the existing implementation in nearly all cases, sometimes significantly. We have not yet spent any time micro-optimizing the implementation and have many unimplemented major improvements, such as fast-paths for trivial goals.

### Unstable features

#### Unsupported unstable features

The new solver currently does not support all unstable features, most notably `#![feature(generic_const_exprs)]`, `#![feature(associated_const_equality)]` and `#![feature(adt_const_params)]` are not yet fully supported in the new solver. We are confident that supporting them is possible, but did not consider this to be a priority. This stabilization introduces new ICE when using these features in impl headers.

#### fixes to `#![feature(specialization)]`

- fixes #105782
- fixes #118987

#### fixes to `#![feature(type_alias_impl_trait)]`

- fixes #119272
- https://github.com/rust-lang/rust/issues/105787#issuecomment-1750112388
- fixes #124207

### Important changes since the original FCP

https://github.com/rust-lang/rust/pull/127574 changes the coherence unknowable candidate to only apply if all the super trait bounds may hold. This allows more code to compile and fixes a regression in `pyella`

https://github.com/rust-lang/rust/pull/130617 bails with ambiguity if the query response would contain too many non-region inference variables. This should only be triggered in case the result contains a lot of ambiguous aliases in which case further constraining the goal should resolve this.

https://github.com/rust-lang/rust/pull/130821 adds caching to a lot of type folders, which is necessary to handle exponentially large types and handles the hang in `nalgebra` together with #130617.

## This does not stabilize the whole solver

While this stabilizes the use of the new solver in coherence checking, there are many parts of the solver which will remain fully unstable. We may still adapt these areas while working towards stabilizing the new solver everywhere. We are confident that we are able to do so without negatively impacting coherence.

### goals with a non-empty `ParamEnv`

Coherence always uses an empty environment. We therefore do not depend on the behavior of `AliasBound` and `ParamEnv` candidates. We only stabilizes the behavior of user-defined and builtin implementations of traits. There are still many open questions there.

### opaque types in the defining scope

The handling of opaque types - `impl Trait` - in both the new and old solver is still not fully figured out. Luckily this can be ignored for now. While opaque types are reachable during coherence checking by using `impl_trait_in_associated_types`, the behavior during coherence is separate and self-contained. The old and new solver fully agree here.

### normalization is hard

This stabilizes that we equate associated types involving bound variables using deferred-alias-equality. We also stop eagerly normalizing in coherence, which should not have any user-facing impact.

We do not stabilize the normalization behavior outside of coherence, e.g. we currently deeply normalize all types during writeback with the new solver. This may change going forward

### how to replace `select` from the old solver

We sometimes depend on getting a single `impl` for a given trait bound, e.g. when resolving a concrete method for codegen/CTFE. We do not depend on this during coherence, so the exact approach here can still be freely changed going forward.

## Acknowledgements

This work would not have been possible without `@compiler-errors.` He implemented large chunks of the solver himself but also and did a lot of testing and experimentation, eagerly discovering multiple issues which had a significant impact on our approach. `@BoxyUwU` has also done some amazing work on the solver. Thank you for the endless hours of discussion resulting in the current approach. Especially the way aliases are handled has gone through multiple revisions to get to its current state.

There were also many contributions from - and discussions with - other members of the community and the rest of `@rust-lang/types.` This solver builds upon previous improvements to the compiler, as well as lessons learned from `chalk` and `a-mir-formality`. Getting to this point  would not have been possible without that and I am incredibly thankful to everyone involved. See the [list of relevant PRs](https://github.com/rust-lang/rust/pulls?q=is%3Apr+is%3Amerged+label%3AWG-trait-system-refactor+-label%3Arollup+closed%3A%3C2024-03-22+).
2024-10-15 14:21:34 +00:00
Guillaume Gomez
10f2395c9e Remove AmbiguousLinks::disambiguator 2024-10-15 15:42:53 +02:00
Guillaume Gomez
2b9e41c128 Improve documentation for intra-doc links computation 2024-10-15 15:42:53 +02:00
zlfn
99af761632 Refactor floating macro and nofloat panic message 2024-10-15 22:27:06 +09:00
Hood Chatham
1d6643c4f6 Fix most ui tests on emscripten target
To fix the linker errors, we need to set the output extension to `.js` instead
of `.wasm`. Setting the output to a `.wasm` file puts Emscripten into standalone
mode which is effectively a distinct target. We need to set the runner to be
`node` as well.

This fixes most of the ui tests. I fixed a few more tests with simple problems:
- `intrinsics/intrinsic-alignment.rs` and `structs-enums/rec-align-u64.rs` --
Two `#[cfg]` macros match for Emscripten so we got a duplicate definition of
`mod m`.
- `issues/issue-12699.rs` -- Seems to hang so I disabled it
- `process/process-sigpipe.rs` -- Not expected to work on Emscripten so I
disabled it
2024-10-15 14:25:55 +02:00
Emmanuel Ferdman
4e29e454a1
Update arm64e-apple-tvos maintainer
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2024-10-15 05:12:03 -07:00
bors
f79fae3069 Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #122670 (Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode)
 - #131095 (Use environment variables instead of command line arguments for merged doctests)
 - #131339 (Expand set_ptr_value / with_metadata_of docs)
 - #131652 (Move polarity into `PolyTraitRef` rather than storing it on the side)
 - #131675 (Update lint message for ABI not supported)
 - #131681 (Fix up-to-date checking for run-make tests)
 - #131702 (Suppress import errors for traits that couldve applied for method lookup error)
 - #131703 (Resolved python deprecation warning in publish_toolstate.py)
 - #131710 (Remove `'apostrophes'` from `rustc_parse_format`)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-15 11:50:31 +00:00
bors
c16ba359b5 Auto merge of #131723 - matthiaskrgr:rollup-krcslig, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #122670 (Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode)
 - #131095 (Use environment variables instead of command line arguments for merged doctests)
 - #131339 (Expand set_ptr_value / with_metadata_of docs)
 - #131652 (Move polarity into `PolyTraitRef` rather than storing it on the side)
 - #131675 (Update lint message for ABI not supported)
 - #131681 (Fix up-to-date checking for run-make tests)
 - #131702 (Suppress import errors for traits that couldve applied for method lookup error)
 - #131703 (Resolved python deprecation warning in publish_toolstate.py)
 - #131710 (Remove `'apostrophes'` from `rustc_parse_format`)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-15 11:50:31 +00:00
Michal Piotrowski
d3d59055a9
Fix uninlined_format_args in stable_mir 2024-10-15 13:49:07 +02:00
lcnr
30ec8bb5e9 update test description 2024-10-15 13:26:59 +02:00
lcnr
7aeb07a583 remove unnecessary revisions 2024-10-15 13:26:59 +02:00
lcnr
d3f982d466 rebase and update fixed crashes 2024-10-15 13:11:00 +02:00
lcnr
1a9d2d82a5 stabilize -Znext-solver=coherence 2024-10-15 13:11:00 +02:00
Julian Frimmel
db6c736da3
Allow the compiler to select any register 2024-10-15 12:30:55 +02:00
Julian Frimmel
652ba6699c
Add check-annotations ensuring correct label
The issue was, that the disassembled label was placed one instruction
further down than expected. Therefore the test annotations check, that
the label is placed above the loop-contents (writing the one value, then
writing the other one).
2024-10-15 12:23:35 +02:00
Julian Frimmel
da44e3fdce
Start test case for rjmp regression test
This commit introduces a minimal `![no_core]`-test case running on AVR,
that contains the MCWE mentioned in [129301]. The test case itself does
not have any assertions yet, but it shows the minimal set an language
items necessary within the test case.

[129301]: https://github.com/rust-lang/rust/issues/129301#issuecomment-2301399472
2024-10-15 12:22:37 +02:00
zlfn
0637517da6 Rename debug! macro to impl_Debug! 2024-10-15 18:32:21 +09:00
zlfn
918dc38733 Combine impl_int and impl_uint
Two macros are exactly the same.
2024-10-15 18:23:39 +09:00
Eduardo Sánchez Muñoz
c09ed3e767 Make some float methods unstable const fn
Some float methods are now `const fn` under the `const_float_methods` feature gate.

In order to support `min`, `max`, `abs` and `copysign`, the implementation of some intrinsics had to be moved from Miri to rustc_const_eval.
2024-10-15 10:46:33 +02:00
bors
00367d523e Auto merge of #131727 - RalfJung:miri-sync, r=RalfJung
Miri subtree update

r? `@ghost`
2024-10-15 08:42:24 +00:00
bors
6bb6fd861b Auto merge of #18278 - ShoyuVanilla:never-place, r=Veykril
Do not consider match/let/ref of place that evaluates to ! to diverge, disallow coercions from them too

Resolves #18237
2024-10-15 07:29:55 +00:00
bors
be1c31d9a9 Auto merge of #18299 - roife:fix-issue-18298, r=Veykril
fix: incorrect autofix for missing wrapped unit in return expr

fix #18298.

We should insert `Ok(())` or `Some(())` instead of wrapping `return` with variants.
2024-10-15 07:13:44 +00:00
roife
d381df43c4 fix: autofix for missing wrapped unit in return expr 2024-10-15 14:23:58 +08:00
Ralf Jung
1f501a7f09 update lockfile 2024-10-15 07:51:50 +02:00
bors
88f311479d Auto merge of #131724 - matthiaskrgr:rollup-ntgkkk8, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #130608 (Implemented `FromStr` for `CString` and `TryFrom<CString>` for `String`)
 - #130635 (Add `&pin (mut|const) T` type position sugar)
 - #130747 (improve error messages for `C-cmse-nonsecure-entry` functions)
 - #131137 (Add 1.82 release notes)
 - #131328 (Remove unnecessary sorts in `rustc_hir_analysis`)
 - #131496 (Stabilise `const_make_ascii`.)
 - #131706 (Fix two const-hacks)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-10-15 05:02:38 +00:00
Matthias Krüger
83252bd780
Rollup merge of #131706 - GKFX:fix-const-hacks, r=tgross35
Fix two const-hacks

Fix two pieces of code marked `FIXME(const-hack)` related to const_option #67441.
2024-10-15 05:12:37 +02:00
Matthias Krüger
9716a42389
Rollup merge of #131496 - bjoernager:const-make-ascii, r=dtolnay
Stabilise `const_make_ascii`.

Closes: #130698

This PR stabilises the `const_make_ascii` feature gate (i.e. marking the `make_ascii_uppercase` and `make_ascii_lowercase` methods in `char`, `u8`, `[u8]`, and `str` as const).
2024-10-15 05:12:36 +02:00
Matthias Krüger
b9cb20154d
Rollup merge of #131328 - ismailarilik:remove-unnecessary-sorts-in-rustc-hir-analysis, r=compiler-errors
Remove unnecessary sorts in `rustc_hir_analysis`

A follow-up after #131140. Here the related objects are `IndexSet` so do not require a sort to stay stable. And they don't need to be `mut` anymore.

r? ```@compiler-errors```
2024-10-15 05:12:36 +02:00
Matthias Krüger
13e07b9edd
Rollup merge of #131137 - Mark-Simulacrum:relnotes, r=cuviper
Add 1.82 release notes

cc ````@rust-lang/release````

This is using the new release notes infrastructure. My expectation is that most and/or all edits should be made separately from this PR by updating various relnote tracking issues, and then we'll re-run the relnotes tool. That probably comes with an exception for the stabilized APIs for std, which will need to be manually added at the end.
2024-10-15 05:12:35 +02:00
Matthias Krüger
731e360d15
Rollup merge of #130747 - folkertdev:c-cmse-nonsecure-entry-error-messages, r=compiler-errors
improve error messages for `C-cmse-nonsecure-entry` functions

fixes https://github.com/rust-lang/rust/issues/81347

tracking issue: https://github.com/rust-lang/rust/issues/75835

brings error messages and testing for `C-cmse-nonsecure-entry` in line with `C-cmse-nonsecure-call`.

r? `@compiler-errors`
2024-10-15 05:12:35 +02:00
Matthias Krüger
66359a7c87 Rollup merge of #130635 - eholk:pin-reborrow-sugar, r=compiler-errors
Add `&pin (mut|const) T` type position sugar

This adds parser support for `&pin mut T` and `&pin const T` references. These are desugared to `Pin<&mut T>` and `Pin<&T>` in the AST lowering phases.

This PR currently includes #130526 since that one is in the commit queue. Only the most recent commits (bd450027eb4a94b814a7dd9c0fa29102e6361149 and following) are new.

Tracking:

- #130494

r? `@compiler-errors`
2024-10-15 05:12:34 +02:00
Matthias Krüger
fb691b470a
Rollup merge of #130635 - eholk:pin-reborrow-sugar, r=compiler-errors
Add `&pin (mut|const) T` type position sugar

This adds parser support for `&pin mut T` and `&pin const T` references. These are desugared to `Pin<&mut T>` and `Pin<&T>` in the AST lowering phases.

This PR currently includes #130526 since that one is in the commit queue. Only the most recent commits (bd450027eb4a94b814a7dd9c0fa29102e6361149 and following) are new.

Tracking:

- #130494

r? `@compiler-errors`
2024-10-15 05:12:34 +02:00
Matthias Krüger
3a00d35c5d
Rollup merge of #130608 - YohDeadfall:cstr-from-into-str, r=workingjubilee
Implemented `FromStr` for `CString` and `TryFrom<CString>` for `String`

The motivation of this change is making it possible to use `CString` in generic methods with `FromStr` and `TryInto<String>` trait bounds. The same traits are already implemented for `OsString` which is an FFI type too.
2024-10-15 05:12:34 +02:00
Matthias Krüger
c99c4d4057
Rollup merge of #131710 - ShE3py:parse_format_apostrophes, r=compiler-errors
Remove `'apostrophes'` from `rustc_parse_format`

The rest of the compiler uses \`grave accents\`, while `rustc_parse_format` uses \`'apostrophes.'\`

Also makes the crate compile as a stand-alone:
```
~/rust/compiler/rustc_parse_format $ cargo check
   Compiling rustc_index_macros v0.0.0 (/home/lieselotte/rust/compiler/rustc_index_macros)
error[E0277]: `syn::Lit` doesn't implement `Debug`
  --> compiler/rustc_index_macros/src/newtype.rs:52:57
   |
52 |                         panic!("Specified multiple max: {old:?}");
   |                                                         ^^^^^^^ `syn::Lit` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `syn::Lit`
   = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: `syn::Lit` doesn't implement `Debug`
  --> compiler/rustc_index_macros/src/newtype.rs:64:74
   |
64 |                         panic!("Specified multiple debug format options: {old:?}");
   |                                                                          ^^^^^^^ `syn::Lit` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = help: the trait `Debug` is not implemented for `syn::Lit`
   = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.
error: could not compile `rustc_index_macros` (lib) due to 2 previous errors
```
`@rustbot` label +A-diagnostics
2024-10-15 05:11:40 +02:00
Matthias Krüger
d82a49dba2
Rollup merge of #131703 - alex:patch-1, r=Kobzol
Resolved python deprecation warning in publish_toolstate.py

`utcnow()` is deprecated in favor of passing a timezone to `now()`. `utcnow()` would return a tz-naive datetime, while this returns a tz-aware datetime. For the purposes of the formatting we do, these are the same.
2024-10-15 05:11:39 +02:00
Matthias Krüger
2e2c433be4
Rollup merge of #131702 - compiler-errors:method-lookup-trait-warning, r=jieyouxu
Suppress import errors for traits that couldve applied for method lookup error

Self-explanatory. I hit this quite often when refactoring in rustc, so even though this isn't really showing up as significant in the UI test suite, it probably will matter more for multi-module projects.
2024-10-15 05:11:39 +02:00
Matthias Krüger
258c17741b
Rollup merge of #131681 - Zalathar:fix-run-make-stamp, r=jieyouxu
Fix up-to-date checking for run-make tests

This special case in `output_base_dir` had the unfortunate side-effect of causing all run-make tests to share the same `stamp` file. So as soon as any one of them succeeded, all of the failed tests would be incorrectly considered up-to-date and would no longer run in subsequent test invocations.

Fixes #129971.

r? jieyouxu
2024-10-15 05:11:38 +02:00
Matthias Krüger
bd649b4dd0
Rollup merge of #131675 - tdittr:update-unsupported-abi-message, r=compiler-errors
Update lint message for ABI not supported

Tracking issue: #130260

As requested in https://github.com/rust-lang/rust/pull/128784#pullrequestreview-2364026550 I updated the error message.

I could also change it to be the same message as if it was a hard error on a normal function:

> "`{abi}` is not a supported ABI for the current target"

Or would that get confusing when people try to google the error message?

r? compiler-errors
2024-10-15 05:11:38 +02:00
Matthias Krüger
4d53a28cac
Rollup merge of #131652 - compiler-errors:modifiers, r=Nadrieril,jieyouxu
Move polarity into `PolyTraitRef` rather than storing it on the side

Arguably we could move these modifiers into `TraitRef` instead of `PolyTraitRef`, but I see `TraitRef` as simply the *path* part of the trait ref. It doesn't really matter -- refactoring this further is much easier now.
2024-10-15 05:11:37 +02:00
Matthias Krüger
09103f2617
Rollup merge of #131339 - HeroicKatora:set_ptr_value-documentation, r=Mark-Simulacrum
Expand set_ptr_value / with_metadata_of docs

In preparation of a potential FCP, intends to clean up and expand the documentation of this operation.

Rewrite these blobs to explicitly mention the case of a sized operand. The previous made that seem wrong instead of emphasizing it is nothing but a simple cast. Instead, the explanation now emphasizes that the address portion of the argument, together with its provenance, is discarded which previously had to be inferred by the reader. Then an example demonstrates a simple line of incorrect usage based on this idea of provenance.

Tracking issue: https://github.com/rust-lang/rust/issues/75091
2024-10-15 05:11:37 +02:00
Matthias Krüger
bb2f970604
Rollup merge of #131095 - GuillaumeGomez:switch-to-env-variables, r=notriddle
Use environment variables instead of command line arguments for merged doctests

Fixes [#130796](https://github.com/rust-lang/rust/issues/130796).

Before merging this one, let's first ensure it has a smaller impact compared to command line arguments (results can be seen [here](https://github.com/rust-lang/rust/pull/130285)). I'll start a crater run once CI passed.

cc ``@ehuss``
r? ``@notriddle``
2024-10-15 05:11:36 +02:00
Matthias Krüger
6d9999662c
Rollup merge of #122670 - beetrees:non-unicode-option-env-error, r=compiler-errors
Fix bug where `option_env!` would return `None` when env var is present but not valid Unicode

Fixes #122669 by making `option_env!` emit an error when the value of the environment variable is not valid Unicode.
2024-10-15 05:11:36 +02:00
bors
785c83015c Auto merge of #129458 - EnzymeAD:enzyme-frontend, r=jieyouxu
Autodiff Upstreaming - enzyme frontend

This is an upstream PR for the `autodiff` rustc_builtin_macro that is part of the autodiff feature.

For the full implementation, see: https://github.com/rust-lang/rust/pull/129175

**Content:**
It contains a new `#[autodiff(<args>)]` rustc_builtin_macro, as well as a `#[rustc_autodiff]` builtin attribute.
The autodiff macro is applied on function `f` and will expand to a second function `df` (name given by user).
It will add a dummy body to `df` to make sure it type-checks. The body will later be replaced by enzyme on llvm-ir level,
we therefore don't really care about the content. Most of the changes (700 from 1.2k) are in `compiler/rustc_builtin_macros/src/autodiff.rs`, which expand the macro. Nothing except expansion is implemented for now.
I have a fallback implementation for relevant functions in case that rustc should be build without autodiff support. The default for now will be off, although we want to flip it later (once everything landed) to on for nightly. For the sake of CI, I have flipped the defaults, I'll revert this before merging.

**Dummy function Body:**
The first line is an `inline_asm` nop to make inlining less likely (I have additional checks to prevent this in the middle end of rustc. If `f` gets inlined too early, we can't pass it to enzyme and thus can't differentiate it.
If `df` gets inlined too early, the call site will just compute this dummy code instead of the derivatives, a correctness issue. The following black_box lines make sure that none of the input arguments is getting optimized away before we replace the body.

**Motivation:**
The user facing autodiff macro can verify the user input. Then I write it as args to the rustc_attribute, so from here on I can know that these values should be sensible. A rustc_attribute also turned out to be quite nice to attach this information to the corresponding function and carry it till the backend.
This is also just an experiment, I expect to adjust the user facing autodiff macro based on user feedback, to improve usability.

As a simple example of what this will do, we can see this expansion:
From:
```
#[autodiff(df, Reverse, Duplicated, Const, Active)]
pub fn f1(x: &[f64], y: f64) -> f64 {
    unimplemented!()
}
```
to
```
#[rustc_autodiff]
#[inline(never)]
pub fn f1(x: &[f64], y: f64) -> f64 {
    ::core::panicking::panic("not implemented")
}
#[rustc_autodiff(Reverse, Duplicated, Const, Active,)]
#[inline(never)]
pub fn df(x: &[f64], dx: &mut [f64], y: f64, dret: f64) -> f64 {
    unsafe { asm!("NOP"); };
    ::core::hint::black_box(f1(x, y));
    ::core::hint::black_box((dx, dret));
    ::core::hint::black_box(f1(x, y))
}
```
I will add a few more tests once I figured out why rustc rebuilds every time I touch a test.

Tracking:

- https://github.com/rust-lang/rust/issues/124509

try-job: dist-x86_64-msvc
2024-10-15 01:30:01 +00:00
Gabriel Bjørnager Jensen
3c31729887
Stabilise 'const_make_ascii' 2024-10-14 17:56:36 -07:00
bors
eb5ca5f53c Auto merge of #3974 - RalfJung:check_min_arg_count, r=RalfJung
use new check_min_arg_count helper in more places
2024-10-14 21:41:07 +00:00
Ralf Jung
413ea993de use new check_min_arg_count helper in more places 2024-10-14 23:37:03 +02:00
Lieselotte
dda3066805
Remove 'apostrophes' from rustc_parse_format 2024-10-14 23:22:51 +02:00
Trevor Gross
373142aaa1 Mark LazyCell::into_inner unstably const
Other cell `into_inner` functions are const and there shouldn't be any
problem here. Make the unstable `LazyCell::into_inner` const under the
same gate as its stability (`lazy_cell_into_inner`).

Tracking issue: https://github.com/rust-lang/rust/issues/125623
2024-10-14 17:16:01 -04:00