Commit Graph

265238 Commits

Author SHA1 Message Date
Matthias Krüger
ccf3f6e59d
Rollup merge of #126452 - compiler-errors:raw-lifetimes, r=spastorino
Implement raw lifetimes and labels (`'r#ident`)

This PR does two things:
1. Reserve lifetime prefixes, e.g. `'prefix#lt` in edition 2021.
2. Implements raw lifetimes, e.g. `'r#async` in edition 2021.

This PR additionally extends the `keyword_idents_2024` lint to also check lifetimes.

cc `@traviscross`
r? parser
2024-09-07 23:30:10 +02:00
bors
ec867f03bc Auto merge of #126161 - Bryanskiy:delegation-generics-4, r=petrochenkov
Delegation: support generics in associated delegation items

This is a continuation of https://github.com/rust-lang/rust/pull/125929.

[design](https://github.com/Bryanskiy/posts/blob/master/delegation%20in%20generic%20contexts.md)

Generic parameters inheritance was implemented in all contexts. Generic arguments are not yet supported.

r? `@petrochenkov`
2024-09-07 18:12:05 +00:00
bors
4ff16a9770 Auto merge of #130066 - compiler-errors:rollup-sq6l0va, r=compiler-errors
Rollup of 9 pull requests

Successful merges:

 - #128871 (bypass linker configuration and cross target check for specific commands)
 - #129468 ([testsuite][cleanup] Remove all usages of `dont_merge` hack to avoid function merging)
 - #129614 (Adjust doc comment of Condvar::wait_while)
 - #129840 (Implement suggestions for `elided_named_lifetimes`)
 - #129891 (Do not request sanitizers for naked functions)
 - #129899 (Add Suggestions for Misspelled Keywords)
 - #129940 (s390x: Fix a regression related to backchain feature)
 - #129987 (Don't store region in `CapturedPlace`)
 - #130054 (Add missing quotation marks)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-09-07 15:47:14 +00:00
bors
7468b6907c Auto merge of #128871 - onur-ozkan:128180, r=Kobzol
bypass linker configuration and cross target check for specific commands

Avoids configuring the linker and checking cross-target-specific tools unless necessary.

Resolves #128180

cc `@ChrisDenton`
2024-09-07 13:21:44 +00:00
Michael Goulet
b09b7da010
Rollup merge of #130054 - cuishuang:master, r=chenyukang
Add missing quotation marks
2024-09-07 14:21:23 +03:00
Michael Goulet
9936179769
Rollup merge of #129987 - compiler-errors:capture-place-region, r=davidtwco
Don't store region in `CapturedPlace`

It's not necessary anymore, since we erase all regions in writeback anyways.
2024-09-07 14:21:23 +03:00
Michael Goulet
bc2244f027
Rollup merge of #129940 - liushuyu:s390x-target-features, r=RalfJung
s390x: Fix a regression related to backchain feature

In #127506, we introduced a new IBM Z-specific target feature, `backchain`.

This particular `target-feature` was available as a function-level attribute in LLVM 17 and below, so some hacks were used to avoid blowing up LLVM when querying the supported LLVM features.

This led to an unfortunate regression where `cfg!(target-feature = "backchain")` will always return true.

This pull request aims to fix this issue, and a test has been introduced to ensure it will never happen again.

Fixes #129927.

r? `@RalfJung`
2024-09-07 14:21:22 +03:00
Michael Goulet
d6a42983e5
Rollup merge of #129899 - veera-sivarajan:fix-97793-pr-final, r=chenyukang
Add Suggestions for Misspelled Keywords

Fixes #97793

This PR detects misspelled keywords using two heuristics:

1. Lowercasing the unexpected identifier.
2. Using edit distance to find a keyword similar to the unexpected identifier.

However, it does not detect each and every misspelled keyword to
minimize false positives and ambiguities. More details about the
implementation can be found in the comments.
2024-09-07 14:21:22 +03:00
Michael Goulet
6dd07e4e26
Rollup merge of #129891 - nikic:naked-no-san, r=jackh726
Do not request sanitizers for naked functions

Naked functions can only contain inline asm, so any instrumentation inserted by sanitizers is illegal. Don't request it.

Fixes https://github.com/rust-lang/rust/issues/129224.
2024-09-07 14:21:21 +03:00
Michael Goulet
41a20dcb87
Rollup merge of #129840 - GrigorenkoPV:elided-named-lifetimes-suggestion, r=cjgillot
Implement suggestions for `elided_named_lifetimes`

A follow-up to #129207, as per https://github.com/rust-lang/rust/pull/129207#issuecomment-2308992849.

r? cjgillot

I will probably squash this a bit, but later.

`@rustbot` label +A-lint
2024-09-07 14:21:20 +03:00
Michael Goulet
040be55550
Rollup merge of #129614 - rawler:patch-1, r=tgross35
Adjust doc comment of Condvar::wait_while

The existing phrasing implies that a notification must be received for `wait_while` to return. The phrasing is changed to make no such implication.
2024-09-07 14:21:20 +03:00
Michael Goulet
adcee23a95
Rollup merge of #129468 - Rajveer100:hack-to-avoid-function-merging, r=Mark-Simulacrum
[testsuite][cleanup] Remove all usages of `dont_merge` hack to avoid function merging

Resolves #129438

The `-Zmerge-functions=disabled` compile flag exists for this purpose.
2024-09-07 14:21:19 +03:00
Michael Goulet
5a2ebb58c4
Rollup merge of #128871 - onur-ozkan:128180, r=Kobzol
bypass linker configuration and cross target check for specific commands

Avoids configuring the linker and checking cross-target-specific tools unless necessary.

Resolves #128180

cc `@ChrisDenton`
2024-09-07 14:21:18 +03:00
Veera
14e86eb7d9 Add Suggestions for Misspelled Keywords
This PR detects misspelled keywords using two heuristics:

1. Lowercasing the unexpected identifier.
2. Using edit distance to find a keyword similar to the unexpected identifier.

However, it does not detect each and every misspelled keyword to
minimize false positives and ambiguities. More details about the
implementation can be found in the comments.
2024-09-06 23:07:45 -04:00
bors
9afe713695 Auto merge of #129341 - madsmtm:refactor-deployment-target, r=petrochenkov
Apple: Refactor deployment target version parsing

Refactor deployment target parsing to make it easier to do https://github.com/rust-lang/rust/pull/129342 (I wanted to make sure of all the places that `std::env::var` is called).

Specifically, my goal was to minimize the amount of target-specific configuration, so to that end I renamed the `opts` function that generates the `TargetOptions` to `base`, and made it return the LLVM target and `target_arch` too. In the future, I would like to move even more out of the target files and into `spec::apple`, as it makes it easier for me to maintain.

For example, this fixed a bug in `aarch64-apple-watchos`, which wasn't passing the deployment target as part of the LLVM triple. This (probably) fixes https://github.com/rust-lang/rust/issues/123582 and fixes https://github.com/rust-lang/rust/issues/107630.

We also now parse the patch version of deployment targets, allowing the user to specify e.g. `MACOSX_DEPLOYMENT_TARGET=10.12.6`.

Finally, this fixes the LLVM target name for visionOS, it should be `*-apple-xros` and not `*-apple-visionos`.

Since I have changed all the Apple targets here, I smoke-tested my changes by running the following:
```console
# Build each target
./x build library --target="aarch64-apple-darwin,aarch64-apple-ios,aarch64-apple-ios-macabi,aarch64-apple-ios-sim,aarch64-apple-tvos,aarch64-apple-tvos-sim,aarch64-apple-visionos,aarch64-apple-visionos-sim,aarch64-apple-watchos,aarch64-apple-watchos-sim,arm64_32-apple-watchos,arm64e-apple-ios,armv7k-apple-watchos,armv7s-apple-ios,i386-apple-ios,x86_64-apple-darwin,x86_64-apple-ios,x86_64-apple-ios-macabi,x86_64-apple-tvos,x86_64-apple-watchos-sim,x86_64h-apple-darwin"

# Test that we can still at least link basic projects
cargo new foobar && cd foobar && cargo +stage1 build --target=aarch64-apple-darwin --target=aarch64-apple-ios --target=aarch64-apple-ios-macabi --target=aarch64-apple-ios-sim --target=aarch64-apple-tvos --target=aarch64-apple-tvos-sim --target=aarch64-apple-visionos --target=aarch64-apple-visionos-sim --target=aarch64-apple-watchos --target=aarch64-apple-watchos-sim --target=arm64_32-apple-watchos --target=armv7s-apple-ios --target=i386-apple-ios --target=x86_64-apple-darwin --target=x86_64-apple-ios --target=x86_64-apple-ios-macabi --target=x86_64-apple-tvos --target=x86_64-apple-watchos-sim --target=x86_64h-apple-darwin
```

I couldn't build for the `arm64e-apple-darwin` target, the `armv7k-apple-watchos` and `arm64e-apple-ios` targets failed to link, and I know that the `i686-apple-darwin` target requires a bit of setup, but all of this is as it was before this PR.

r? thomcc

CC `@BlackHoleFox`

I would recommend using `rollup=never` when merging this, in case we need to bisect this later.
2024-09-07 01:37:52 +00:00
cuishuang
be10d56039 Add missing quotation marks
Signed-off-by: cuishuang <imcusg@gmail.com>
2024-09-07 09:23:28 +08:00
bors
26b5599e4d Auto merge of #128776 - Bryanskiy:deep-reject-ctxt, r=lcnr
Use `DeepRejectCtxt` to quickly reject `ParamEnv` candidates

The description is on the [zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/144729-t-types/topic/.5Basking.20for.20help.5D.20.60DeepRejectCtxt.60.20for.20param.20env.20candidates)

r? `@lcnr`
2024-09-06 19:50:48 +00:00
Michael Goulet
b6a86bee87 Fix tools 2024-09-06 10:32:48 -04:00
Michael Goulet
5054e8cba8 Lint against keyword lifetimes in keyword_idents 2024-09-06 10:32:48 -04:00
Michael Goulet
afa24f0180 Add some more tests 2024-09-06 10:32:48 -04:00
Michael Goulet
97910580aa Add initial support for raw lifetimes 2024-09-06 10:32:48 -04:00
Michael Goulet
3b3e43a386 Format lexer 2024-09-06 10:32:48 -04:00
Michael Goulet
9aaf873396 Reserve prefix lifetimes too 2024-09-06 10:32:48 -04:00
Pavel Grigorenko
9e2d264fa2 Hack around a conflict with clippy::needless_lifetimes 2024-09-06 17:06:35 +03:00
bors
17b322fa69 Auto merge of #121848 - lcnr:stabilize-next-solver, r=compiler-errors
stabilize `-Znext-solver=coherence`

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.

## 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 in #119820.[^leak_check]

[^leak_check]: which should get moved to the dev-guide once that PR lands :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.

TODO: get some rough results here and put them in a table

### 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

## 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-09-06 13:12:14 +00:00
Pavel Grigorenko
547db4a4b7 elided_named_lifetimes: manually implement LintDiagnostic 2024-09-06 15:47:52 +03:00
Pavel Grigorenko
dcfc71310d elided_named_lifetimes: add suggestions 2024-09-06 15:47:52 +03:00
Pavel Grigorenko
e38764d73b elided_named_lifetimes: unify lint def & pass MissingLifetimeKind 2024-09-06 15:47:52 +03:00
Nikita Popov
54ebb9d489 Do not request sanitizers for naked functions
Naked functions can only contain inline asm, so any instrumentation
inserted by sanitizers is illegal. Don't request it.

Fixes https://github.com/rust-lang/rust/issues/129224.
2024-09-06 14:11:13 +02:00
Ulrik Mikaelsson
96837dcade Adjust doc comment of Condvar::wait_while
The existing phrasing implies that a notification must be received for `wait_while` to return. The phrasing is changed to better reflect the behavior.
2024-09-06 13:36:09 +02:00
bors
59d4114b2d Auto merge of #129176 - EnzymeAD:enzyme-backend, r=albertlarsan68
Autodiff Upstreaming - enzyme backend

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

Part of https://github.com/rust-lang/rust/pull/129175

This PR should allow building Enzyme from source on Tier 1 targets (when also building LLVM), except MSVC.
It's only a small fraction (~200 lines) of the whole upstream PR, but due to bootstrapping and the number of configurations in which rustc can be build I assume that this will be the hardest to merge, so I'm starting with it.
Happy to hear what changes are required to be able to upstream this code.

**Content:**
It contains a new configure flag `--enable-llvm-enzyme`, and will build the new Enzyme submodule when it is set.

**Discussion:**
Apparently Rust CI isn't able to clone repositories outside the rust-lang org? At least I'm seeing this error in CI:
```
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
Does that mean we would need to mirror github.com/EnzymeAD/Enzyme in rust-lang, until LLVM upgrades Enzyme from an Incubator project to something that ships as part of the monorepo?

Tracking:

- https://github.com/rust-lang/rust/issues/124509
2024-09-06 09:42:37 +00:00
bors
a3af2085cc Auto merge of #130016 - matthiaskrgr:rollup-fopistw, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #129021 (Check WF of source type's signature on fn pointer cast)
 - #129781 (Make `./x.py <cmd> compiler/<crate>` aware of the crate's features)
 - #129963 (Inaccurate `{Path,OsStr}::to_string_lossy()` documentation)
 - #129969 (Make `Ty::boxed_ty` return an `Option`)
 - #129995 (Remove wasm32-wasip2's tier 2 status from release notes)
 - #130013 (coverage: Count await when the Future is immediately ready )

r? `@ghost`
`@rustbot` modify labels: rollup
2024-09-06 07:18:50 +00:00
Matthias Krüger
11d5614a74
Rollup merge of #130013 - jonathan-conder:await_coverage, r=Zalathar
coverage: Count await when the Future is immediately ready

Currently `await` is only counted towards coverage if the containing
function is suspended and resumed at least once. This is because it
expands to code which contains a branch on the discriminant of `Poll`.

By treating it like a branching macro (e.g. `assert!`), these
implementation details will be hidden from the coverage results.

I added a test to ensure the fix works in simple cases, but the heuristic of picking only the first await-related covspan might be unreliable. I plan on testing more thoroughly with a real codebase over the next couple of weeks.

closes #98712
2024-09-06 07:33:59 +02:00
Matthias Krüger
6841e35420
Rollup merge of #129995 - alexcrichton:remove-wasm32-wasip2-release-notes, r=pietroalbini
Remove wasm32-wasip2's tier 2 status from release notes

It turns out the stars did not actually align for this to get released in Rust 1.81 alas. Full tier 2 status for `wasm32-wasip2` required two PRs:

* #126967 - this made it into Rust 1.81
* #127867 - this didn't make the cut and is in Rust 1.82 instead

This wasn't caught until just after today's release so the plan is to remove the release notes for 1.81 and coordinate to instead add these as release notes to 1.82.
2024-09-06 07:33:58 +02:00
Matthias Krüger
0180b8fff0
Rollup merge of #129969 - GrigorenkoPV:boxed-ty, r=compiler-errors
Make `Ty::boxed_ty` return an `Option`

Looks like a good place to use Rust's type system.

---

Most of 4ac7bcbaad/compiler/rustc_middle/src/ty/sty.rs (L971-L1963) looks like it could be moved to `TyKind` (then I guess  `Ty` should be made to deref to `TyKind`).
2024-09-06 07:33:58 +02:00
Matthias Krüger
45d6957f24
Rollup merge of #129963 - rjooske:fix/inaccurate_to_string_lossy_doc, r=workingjubilee
Inaccurate `{Path,OsStr}::to_string_lossy()` documentation

The documentation of `Path::to_string_lossy()` and `OsStr::to_string_lossy()` says the following:
> Any non-Unicode sequences are replaced with `U+FFFD REPLACEMENT CHARACTER`

which didn't immediately make sense to me. ("non-Unicode sequences"?)
Since both `to_string_lossy` functions eventually become just a call to `String::from_utf8_lossy`, I believe the documentation meant to say:
> Any *non-UTF-8* sequences are replaced with `U+FFFD REPLACEMENT CHARACTER`

This PR corrects this mistake in the documentation.

For the record, a similar quote can be found in the documentation of `String::from_utf8_lossy`:
> ... During this conversion, `from_utf8_lossy()` will replace any invalid UTF-8 sequences with `U+FFFD REPLACEMENT CHARACTER`, ...
2024-09-06 07:33:57 +02:00
Matthias Krüger
b09f316058
Rollup merge of #129781 - Veykril:lw-x-py-compiler-features, r=albertlarsan68
Make `./x.py <cmd> compiler/<crate>` aware of the crate's features

Does not fix https://github.com/rust-lang/rust/issues/129727 on its own as the way the parallel-compiler cfg and feature flags are setup being generally incompatible with `resolver = 2` but it progresses on the issue. But this should in theory allow compiler crates to work that do not depend on the parallel compiler stuff (so some leaf crates).
2024-09-06 07:33:57 +02:00
Matthias Krüger
e903b29dc3
Rollup merge of #129021 - compiler-errors:ptr-cast-outlives, r=lcnr
Check WF of source type's signature on fn pointer cast

This PR patches the implied bounds holes slightly for #129005, #25860.

Like most implied bounds related unsoundness fixes, this isn't complete w.r.t. higher-ranked function signatures, but I believe it implements a pretty good heuristic for now.

### What does this do?

This PR makes a partial patch for a soundness hole in a `FnDef` -> `FnPtr` "reifying" pointer cast where we were never checking that the signature we are casting *from* is actually well-formed. Because of this, and because `FnDef` doesn't require its signature to be well-formed (just its predicates must hold), we are essentially allowed to "cast away" implied bounds that are assumed within the body of the `FnDef`:

```
fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }

fn bad<'short, T>(x: &'short T) -> &'static T {
    let f: fn(_, &'short T) -> &'static T = foo;
    f(&&(), x)
}
```

In this example, subtyping ends up casting the `_` type (which should be `&'static &'short ()`) to some other type that no longer serves as a "witness" to the lifetime relationship `'short: 'static` which would otherwise be required for this call to be WF. This happens regardless of if `foo`'s lifetimes are early- or late-bound.

This PR implements two checks:
1. We check that the signature of the `FnDef` is well-formed *before* casting it. This ensures that there is at least one point in the MIR where we ensure that the `FnDef`'s implied bounds are actually satisfied by the caller.
2. Implements a special case where if we're casting from a higher-ranked `FnDef` to a non-higher-ranked, we instantiate the binder of the `FnDef` with *infer vars* and ensure that it is a supertype of the target of the cast.

The (2.) is necessary to validate that these pointer casts are valid for higher-ranked `FnDef`. Otherwise, the example above would still pass even if `help`'s `'a` lifetime were late-bound.

### Further work

The WF checks for function calls are scattered all over the MIR. We check the WF of args in call terminators, we check the WF of `FnDef` when we create a `const` operand referencing it, and we check the WF of the return type in #115538, to name a few.

One way to make this a bit cleaner is to simply extend #115538 to always check that the signature is WF for `FnDef` types. I may do this as a follow-up, but I wanted to keep this simple since this leads to some pretty bad NLL diagnostics regressions, and AFAICT this solution is *complete enough*.

### Crater triage

Done here: https://github.com/rust-lang/rust/pull/129021#issuecomment-2297702647

r? lcnr
2024-09-06 07:33:56 +02:00
Jonathan Conder
25d183057e coverage: Treat await similar to a macro
Currently `await` is only counted towards coverage if the containing
function is suspended and resumed at least once. This is because it
expands to code which contains a branch on the discriminant of `Poll`.

By treating it like a branching macro (e.g. `assert!`), these
implementation details will be hidden from the coverage results.
2024-09-06 17:01:59 +12:00
Jonathan Conder
3446ca535e coverage: Add test to codify existing behavior
Currently `await` is only counted towards coverage if the containing
function is suspended and resumed at least once. A future commit will
fix this and update the test to reflect the new behavior.
2024-09-06 16:50:23 +12:00
bors
d678b81485 Auto merge of #129999 - matthiaskrgr:rollup-pzr9c8p, r=matthiaskrgr
Rollup of 11 pull requests

Successful merges:

 - #128919 (Add an internal lint that warns when accessing untracked data)
 - #129472 (fix ICE when `asm_const` and `const_refs_to_static` are combined)
 - #129653 (clarify that addr_of creates read-only pointers)
 - #129775 (bootstrap: Try to track down why `initial_libdir` sometimes fails)
 - #129939 (explain why Rvalue::Len still exists)
 - #129942 (copy rustc rustlib artifacts from ci-rustc)
 - #129943 (use the bootstrapped compiler for `test-float-parse` test)
 - #129944 (Add compat note for trait solver change)
 - #129947 (Add digit separators in `Duration` examples)
 - #129955 (Temporarily remove fmease from the review rotation)
 - #129957 (forward linker option to lint-docs)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-09-06 03:06:52 +00:00
Manuel Drehwald
4f5c16d62f Enzyme backend
Co-authored-by: Lorenz Schmidt <bytesnake@mailbox.org>
2024-09-05 22:47:23 -04:00
bors
54fdef7799 Auto merge of #121614 - clubby789:no-expect, r=saethlin
Don't emit `expect`/`assume` in opt-level=0

LLVM does not make use of expect/assume calls in `opt-level=0`, so we can simplify IR by not emitting them in this case.
2024-09-06 00:42:58 +00:00
Pavel Grigorenko
f6e8a84eea Make Ty::boxed_ty return an Option 2024-09-06 00:30:36 +03:00
bors
9c01301c52 Auto merge of #129994 - matthiaskrgr:rollup-zkj4ekl, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #128820 (fix: get llvm type of global val)
 - #129028 (`impl_trait_overcaptures`: Don't worry about uncaptured contravariant lifetimes if they outlive a captured lifetime)
 - #129471 ([rustdoc] Sort impl associated items by kinds and then by appearance)
 - #129706 (Rename dump of coroutine by-move-body to be more consistent, fix ICE in dump_mir)
 - #129720 (Simplify DestProp memory management)
 - #129796 (Unify scraped examples with other code examples)
 - #129938 (Elaborate on deriving vs implementing `Copy`)
 - #129973 (run_make_support: rename `Command::stdin` to `stdin_buf` and add `std{in,out,err}` config helpers)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-09-05 20:34:38 +00:00
Matthias Krüger
d34ad5d9aa
Rollup merge of #129957 - chenx97:lint-docs-linker-opt, r=albertlarsan68
forward linker option to lint-docs

This fixes an error found when building the doc for a cross-built toolchain.

```
warning: the code example in lint `unstable_syntax_pre_expansion` in /buildroots/chenx97/rustc-1.80.1-src/compiler/rustc_lint_defs/src/builtin.rs failed to generate the expected output: did not find lint `unstable_syntax_p
re_expansion` in output of example, got:

error: linking with `cc` failed: exit status: 1
...
```
Closes: #129956
2024-09-05 19:43:51 +02:00
Matthias Krüger
a0ab808caa
Rollup merge of #129955 - fmease:fmease-break, r=fmease
Temporarily remove fmease from the review rotation

Namely for like a week. I seriously need to work off my review backlog!

r? fmease
2024-09-05 19:43:51 +02:00
Matthias Krüger
96719dbe32
Rollup merge of #129947 - LiterallyVoid:duration-docs-digit-separators, r=tgross35
Add digit separators in `Duration` examples

``@rustbot`` label A-docs
2024-09-05 19:43:50 +02:00
Matthias Krüger
a84ef47841
Rollup merge of #129944 - Mark-Simulacrum:relnotes-tweak, r=pietroalbini
Add compat note for trait solver change

r? ``@pietroalbini`` ``@BoxyUwU``

cc ``@lcnr``
2024-09-05 19:43:50 +02:00
Matthias Krüger
57d85fa0cb
Rollup merge of #129943 - onur-ozkan:test-float-parse-compiler, r=Kobzol
use the bootstrapped compiler for `test-float-parse` test

Fixes https://github.com/rust-lang/rust/pull/122709#issuecomment-2327259336.

Blocker for https://github.com/rust-lang/rust/pull/122709
2024-09-05 19:43:49 +02:00