Commit Graph

4556 Commits

Author SHA1 Message Date
Michael Goulet
d753aba3b3 Get rid of a_is_expected from ToTrace 2024-09-27 15:43:18 -04:00
Michael Goulet
4fb097a5de Instantiate binders when checking supertrait upcasting 2024-09-27 15:43:18 -04:00
Matthias Krüger
a935064fae
Rollup merge of #130826 - fmease:compiler-mv-obj-safe-dyn-compat, r=compiler-errors
Compiler: Rename "object safe" to "dyn compatible"

Completed T-lang FCP: https://github.com/rust-lang/lang-team/issues/286#issuecomment-2338905118.
Tracking issue: https://github.com/rust-lang/rust/issues/130852

Excludes `compiler/rustc_codegen_cranelift` (to be filed separately).
Includes Stable MIR.

Regarding https://github.com/rust-lang/rust/labels/relnotes, I guess I will manually open a https://github.com/rust-lang/rust/labels/relnotes-tracking-issue since this change affects everything (compiler, library, tools, docs, books, everyday language).

r? ghost
2024-09-27 21:35:08 +02:00
Jubilee
6b0c897499
Rollup merge of #130911 - notriddle:notriddle/suggest-wrap-parens-fn-pointer, r=compiler-errors
diagnostics: wrap fn cast suggestions in parens when needed

Fixes #121632
2024-09-26 22:20:56 -07:00
Michael Goulet
d4ee408afc Check allow instantiating object trait binder when upcasting and in new solver 2024-09-26 22:26:29 -04:00
Michael Howell
c48b0d4eb4 diagnostics: wrap fn cast suggestions in parens
Fixes #121632
2024-09-26 18:17:52 -07:00
Scott McMurray
fd5aa07f4f Stabilize the map/value methods on ControlFlow
And fix the stability attribute on the `pub use` in `core::ops`.
2024-09-25 19:00:17 -07:00
León Orell Valerian Liehr
01a063f9df
Compiler: Rename "object safe" to "dyn compatible" 2024-09-25 13:26:48 +02:00
Virginia Senioria
986e20d5bb Fixed diagnostics for coroutines with () as input. 2024-09-25 08:45:40 +00:00
Matthias Krüger
2bca5c4fc1
Rollup merge of #130714 - compiler-errors:try-structurally-resolve-const, r=BoxyUwU
Introduce `structurally_normalize_const`, use it in `rustc_hir_typeck`

Introduces `structurally_normalize_const` to typecking to separate the "eval a const" step from the "try to turn a valtree into a target usize" in HIR typeck, where we may still have infer vars and stuff around.

I also changed `check_expr_repeat` to move a double evaluation of a const into a single one. I'll leave inline comments.

r? ```@BoxyUwU```

I hesitated to really test this on the new solver where it probably matters for unevaluated consts. If you're worried about the side-effects, I'd be happy to craft some more tests 😄
2024-09-23 06:45:36 +02:00
Matthias Krüger
82060368e6
Rollup merge of #130712 - compiler-errors:const-eval-error-reporting, r=BoxyUwU
Don't call `ty::Const::normalize` in error reporting

We do this to ensure that trait refs with unevaluated consts have those consts simplified to their evaluated forms. Instead, use `try_normalize_erasing_regions`.

**NOTE:** This has the side-effect of erasing regions from all of our trait refs. If this is too much to review or you think it's too opinionated of a diagnostics change, then I could split out the effective change (i.e. erasing regions from this impl suggestion) into another PR and have someone else review it.
2024-09-23 06:45:34 +02:00
Michael Goulet
c682aa162b Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
Michael Goulet
01d19d7be9 Don't call try_eval_target_usize in error reporting 2024-09-22 13:55:06 -04:00
Michael Goulet
8f579497f7 Don't call const normalize in error reporting 2024-09-22 13:55:06 -04:00
Michael Goulet
3b8089a320 Introduce structurally_normalize_const, use it in hir_typeck 2024-09-22 13:54:16 -04:00
bors
1d68e6dd1d Auto merge of #127546 - workingjubilee:5-level-paging-exists, r=saethlin
Correct outdated object size limit

The comment here about 48 bit addresses being enough was written in 2016 but was made incorrect in 2019 by 5-level paging, and then persisted for another 5 years before being noticed and corrected.

The bolding of the "exclusive" part is merely to call attention to something I missed when reading it and doublechecking the math.

try-job: i686-msvc
try-job: test-various
2024-09-21 16:20:10 +00:00
Jubilee Young
325af25c94 TL note: current means target 2024-09-20 10:02:14 -07:00
Lukas Markeffsky
1999d065b7 skip normalizing param env if it is already normalized 2024-09-19 15:56:24 +02:00
Matthias Krüger
09b255d3d4
Rollup merge of #130116 - veera-sivarajan:freeze-suggestions, r=chenyukang
Implement a Method to Seal `DiagInner`'s Suggestions

This PR adds a method on `DiagInner` called `.seal_suggestions()` to prevent new suggestions from being added while preserving existing suggestions.

This is useful because currently there is no way to prevent new suggestions from being added to a diagnostic. `.disable_suggestions()` is the closest but it gets rid of all suggestions before and after the call.

Therefore, `.seal_suggestions()` can be used when, for example, misspelled keyword is detected and reported. In such cases, we may want to prevent other suggestions from being added to the diagnostic, as they would likely be meaningless once the misspelled keyword is identified. For context: https://github.com/rust-lang/rust/pull/129899#discussion_r1741307132

To store an additional state, the type of the `suggestions` field in `DiagInner` was changed into a three variant enum. While this change affects files across different crates, care was taken to preserve the existing code's semantics. This is validated by the fact that all UI tests pass without any modifications.

r? chenyukang
2024-09-18 04:42:31 +02:00
Matthias Krüger
62f2ec9b59
Rollup merge of #130275 - compiler-errors:extern-crate, r=lcnr
Don't call `extern_crate` when local crate name is the same as a dependency and we have a trait error

#124944 implemented logic to point out when a trait bound failure involves a *trait* and *type* who come from identically named but different crates. This logic calls the `extern_crate` query which is not valid on `LOCAL_CRATE` cnum, so let's filter that out eagerly.

Fixes #130272
Fixes #129184
2024-09-17 17:28:33 +02:00
León Orell Valerian Liehr
03e8b6bbfa
Rollup merge of #130294 - nnethercote:more-lifetimes, r=lcnr
Lifetime cleanups

The last commit is very opinionated, let's see how we go.

r? `@oli-obk`
2024-09-14 18:12:13 +02:00
Stuart Cook
517e7ce37f
Rollup merge of #130311 - heiseish:issue-70849-fix, r=fmease
(fix) conflicting negative impl marker

## Context

This MR fixes the error message for conflicting negative trait impls by adding the corresponding the polarity marker to the trait name.

## Issues

- closes #70849

r​? `@fmease`
2024-09-14 20:22:41 +10:00
Giang Dao
b0db3a7bed (fix) conflicting negative impl marker and add tests 2024-09-14 09:25:06 +08:00
Nicholas Nethercote
8d32578fe1 Rename and reorder lots of lifetimes.
- Replace non-standard names like 's, 'p, 'rg, 'ck, 'parent, 'this, and
  'me with vanilla 'a. These are cases where the original name isn't
  really any more informative than 'a.
- Replace names like 'cx, 'mir, and 'body with vanilla 'a when the lifetime
  applies to multiple fields and so the original lifetime name isn't
  really accurate.
- Put 'tcx last in lifetime lists, and 'a before 'b.
2024-09-13 15:46:20 +10:00
Veera
741005792e Implement a Method to Seal DiagInner's Suggestions 2024-09-12 21:27:44 -04:00
Matthias Krüger
cb1d80d1e5
Rollup merge of #130273 - lcnr:overflow-no-constraints, r=compiler-errors
more eagerly discard constraints on overflow

We always discard the results of overflowing goals inside of the trait solver. We previously did so when instantiating the response in `evaluate_goal`. Canonicalizing results only to later discard them is also  inefficient 🤷

It's simpler and nicer to debug to eagerly discard constraints inside of the query itself.

r? ``@compiler-errors``
2024-09-12 19:03:43 +02:00
Michael Goulet
9d5d03b7de Don't call extern_crate when local crate name is the same as a dependency and we have a trait error 2024-09-12 09:07:44 -04:00
bors
394c4060d2 Auto merge of #130269 - Zalathar:rollup-coxzt2t, r=Zalathar
Rollup of 8 pull requests

Successful merges:

 - #125060 (Expand documentation of PathBuf, discussing lack of sanitization)
 - #129367 (Fix default/minimum deployment target for Aarch64 simulator targets)
 - #130156 (Add test for S_OBJNAME & update test for LF_BUILDINFO cl and cmd)
 - #130160 (Fix `slice::first_mut` docs)
 - #130235 (Simplify some nested `if` statements)
 - #130250 (Fix `clippy::useless_conversion`)
 - #130252 (Properly report error on `const gen fn`)
 - #130256 (Re-run coverage tests if `coverage-dump` was modified)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-09-12 12:56:55 +00:00
lcnr
675c99f4d5 more eagerly discard constraints on overflow 2024-09-12 14:32:44 +02:00
Stuart Cook
57020e0f8c
Rollup merge of #130250 - compiler-errors:useless-conversion, r=jieyouxu
Fix `clippy::useless_conversion`

Self-explanatory. Probably the last clippy change I'll actually put up since this is the only other one I've actually seen in the wild.
2024-09-12 20:37:17 +10:00
Michael Goulet
e866f8a97d Revert 'Stabilize -Znext-solver=coherence' 2024-09-11 17:57:04 -04:00
Michael Goulet
6d064295c8 clippy::useless_conversion 2024-09-11 17:52:53 -04:00
Michael Goulet
af8d911d63 Also fix if in else 2024-09-11 17:24:01 -04:00
Michael Goulet
954419aab0 Simplify some nested if statements 2024-09-11 13:45:23 -04:00
Jubilee
68ae3b27f5
Rollup merge of #130149 - GrigorenkoPV:lifetime-suggestion, r=cjgillot
Helper function for formatting with `LifetimeSuggestionPosition`
2024-09-09 19:20:38 -07:00
Matthias Krüger
3b0221bf63
Rollup merge of #130137 - gurry:master, r=cjgillot
Fix ICE caused by missing span in a region error

Fixes #130012

The ICE occurs on line 634 in this error handling code: 085744b7ad/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs (L617-L637) It is caused by the span being a dummy span and `!span.is_dummy()` on line 628 evaluating to `false`.

A dummy span, however, is expected here thanks to the `Self: Trait` predicate from `predicates_of` (see line 61): 085744b7ad/compiler/rustc_hir_analysis/src/collect/predicates_of.rs (L61-L69)

This PR changes the error handling code to omit the note which needed the span instead of ICE'ing in the presence of a dummy span.
2024-09-09 20:20:20 +02:00
Pavel Grigorenko
db6361184e Helper function for formatting with LifetimeSuggestionPosition 2024-09-09 14:39:04 +03:00
Jubilee
09373b997d
Rollup merge of #130070 - gurry:rename-regionkind-addof-to-ref, r=compiler-errors
Rename variant `AddrOfRegion` of `RegionVariableOrigin` to `BorrowRegion`

because "Borrow" is the more idiomatic Rust term than "AddrOf".
2024-09-09 00:17:49 -07:00
Gurinder Singh
0f8efb3b5c Fix ICE caused by missing span in a region error 2024-09-09 12:27:36 +05:30
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
Gurinder Singh
c0b06273f2 Rename variant AddrOfRegion of RegionVariableOrigin to BorrowRegion
because "Borrow" is the more idiomatic Rust term than "AddrOf".
2024-09-07 18:50:51 +05:30
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
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
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
Pavel Grigorenko
f6e8a84eea Make Ty::boxed_ty return an Option 2024-09-06 00:30:36 +03:00
Bryanskiy
588dce1421 Delegation: support generics in associated delegation items 2024-09-05 16:04:50 +03:00
lcnr
1a893ac648 stabilize -Znext-solver=coherence 2024-09-05 07:57:16 +00:00
Matthias Krüger
485fd3815c
Rollup merge of #129896 - lcnr:bail-on-unknowable, r=jackh726
do not attempt to prove unknowable goals

In case a goal is unknowable, we previously still checked all other possible ways to prove this goal, even though its final result is already guaranteed to be ambiguous. By ignoring all other candidates in that case we can avoid a lot of unnecessary work, fixing the performance regression in typenum found in #121848.

This is already the behavior in the old solver. This could in theory cause future-compatability issues as considering fewer goals unknowable may end up causing performance regressions/hangs. I am quite confident that this will not be an issue.

r? ``@compiler-errors``
2024-09-03 19:13:26 +02:00
Matthias Krüger
f75a1954eb
Rollup merge of #127692 - veera-sivarajan:bugfix-125139, r=estebank
Suggest `impl Trait` for References to Bare Trait in Function Header

Fixes #125139

This PR suggests `impl Trait` when `&Trait` is found as a function parameter type or return type. This makes use of existing diagnostics by adding `peel_refs()` when checking for type equality.

Additionaly, it makes a few other improvements:
1. Checks if functions inside impl blocks have bare trait in their headers.
2. Introduces a trait `NextLifetimeParamName` similar to the existing `NextTypeParamName` for suggesting a lifetime name. Also, abstracts out the common logic between the two trait impls.

### Related Issues
I ran into a bunch of related diagnostic issues but couldn't fix them within the scope of this PR. So, I have created the following issues:
1. [Misleading Suggestion when Returning a Reference to a Bare Trait from a Function](https://github.com/rust-lang/rust/issues/127689)
2. [Verbose Error When a Function Takes a Bare Trait as Parameter](https://github.com/rust-lang/rust/issues/127690)
3. [Incorrect Suggestion when Returning a Bare Trait from a Function](https://github.com/rust-lang/rust/issues/127691)

r​? ```@estebank``` since you implemented  #119148
2024-09-03 19:13:23 +02:00
lcnr
6188aae369 do not attempt to prove unknowable goals 2024-09-03 08:35:23 +02:00
bors
6199b69c53 Auto merge of #129777 - nnethercote:unreachable_pub-4, r=Urgau
Add `unreachable_pub`, round 4

A follow-up to #129732.

r? `@Urgau`
2024-09-03 01:27:20 +00:00
Nicholas Nethercote
2e358e633d Add warn(unreachable_pub) to rustc_trait_selection. 2024-09-03 08:49:54 +10:00
Matthias Krüger
929b308579
Rollup merge of #129878 - Sajjon:sajjon_fix_typos_batch_3, r=jieyouxu
chore: Fix typos in 'compiler' (batch 3)

Batch 3/3: Fixes typos in `compiler`

(See [issue](https://github.com/rust-lang/rust/issues/129874) tracking all PRs with typos fixes)
2024-09-02 22:35:21 +02:00
Bryanskiy
c51953f4d8 Use DeepRejectCtxt to quickly reject ParamEnv candidates 2024-09-02 19:59:18 +03:00
Alexander Cyon
5780c1ca5e
chore: Fix typos in 'compiler' (batch 3) 2024-09-02 07:33:41 +02:00
Jakub Beránek
47e6b5deed Revert "Auto merge of #127537 - veluca93:struct_tf, r=BoxyUwU"
This reverts commit acb4e8b625, reversing
changes made to 100fde5246.
2024-09-01 16:35:53 +02:00
Matthias Krüger
7d025bb63d
Rollup merge of #129767 - nnethercote:rm-extern-crate-tracing-4, r=jieyouxu
Remove `#[macro_use] extern crate tracing`, round 4

Because explicit importing of macros via use items is nicer (more standard and readable) than implicit importing via #[macro_use]. Continuing the work from #124511, #124914, and #125434. After this PR no `rustc_*` crates use `#[macro_use] extern crate tracing` except for `rustc_codegen_gcc` which is a special case and I will do separately.

r? ```@jieyouxu```
2024-08-31 14:46:11 +02:00
Matthias Krüger
5f10a99c7a
Rollup merge of #129725 - compiler-errors:predicates-of, r=fmease
Stop using `ty::GenericPredicates` for non-predicates_of queries

`GenericPredicates` is a struct of several parts: A list of of an item's own predicates, and a parent def id (and some effects related stuff, but ignore that since it's kinda irrelevant). When instantiating these generic predicates, it calls `predicates_of` on the parent and instantiates its predicates, and appends the item's own instantiated predicates too:

acb4e8b625/compiler/rustc_middle/src/ty/generics.rs (L407-L413)

Notice how this should result in a recursive set of calls to `predicates_of`... However, `GenericPredicates` is *also* misused by a bunch of *other* queries as a convenient way of passing around a list of predicates. For these queries, we don't ever set the parent def id of the `GenericPredicates`, but if we did, then this would be very easy to mistakenly call `predicates_of` instead of some other intended parent query.

Given that footgun, and the fact that we don't ever even *use* the parent def id in the `GenericPredicates` returned from queries like `explicit_super_predicates_of`, It really has no benefit over just returning `&'tcx [(Clause<'tcx>, Span)]`.

This PR additionally opts to wrap the results of `EarlyBinder`, as we've tended to use that in the return type of these kinds of queries to properly convey that the user has params to deal with, and it also gives a convenient way of iterating over a slice of things after instantiating.
2024-08-31 10:08:57 +02:00
Nicholas Nethercote
4b3fa8e9f0 Remove #[macro_use] extern crate tracing from rustc_trait_selection. 2024-08-30 17:14:59 +10:00
Michael Goulet
92004523db Stop using ty::GenericPredicates for non-predicates_of queries 2024-08-29 00:17:40 -04:00
Jubilee
26f75a65d7
Rollup merge of #129343 - estebank:time-version, r=jieyouxu
Emit specific message for time<=0.3.35

```
error[E0282]: type annotations needed for `Box<_>`
  --> /home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
   |
83 |     let items = format_items
   |         ^^^^^
...
86 |     Ok(items.into())
   |              ---- type must be known at this point
   |
   = note: this is an inference error on `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.36`
```

Partially mitigate the fallout from https://github.com/rust-lang/rust/issues/127343. Although the biggest benefit of this would have been if we had had this in 1.80 before it became stable, the long-tail of that change will be felt for a *long* time, so better late than never.

We can also emit an even more targeted error instead of this inference failure.
2024-08-28 19:12:50 -07:00
Esteban Küber
b013a3ddf0 Emit specific message for time<0.3.35 inference failure
```
error[E0282]: type annotations needed for `Box<_>`
  --> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
   |
83 |     let items = format_items
   |         ^^^^^
...
86 |     Ok(items.into())
   |              ---- type must be known at this point
   |
   = note: this is an inference error on crate `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.35`
```

Partially address #127343.
2024-08-28 22:53:02 +00:00
Luca Versari
7eb4cfeace Implement RFC 3525. 2024-08-28 09:54:23 +02:00
Matthias Krüger
d6a3aa4fc4
Rollup merge of #129590 - compiler-errors:ref-tykind, r=fmease
Avoid taking reference of &TyKind

It's already a ref anyways. Just a tiny cleanup here.
2024-08-26 01:49:04 +02:00
Matthias Krüger
6228bd6ef6
Rollup merge of #129405 - surechen:fix_span_x, r=cjgillot
Fixing span manipulation and indentation of the suggestion introduced by #126187

According to comments:
https://github.com/rust-lang/rust/pull/128084#issuecomment-2295254576
https://github.com/rust-lang/rust/pull/126187/files#r1634897691
2024-08-26 01:49:00 +02:00
Michael Goulet
48f43fa0ed Avoid taking reference of &TyKind 2024-08-25 16:02:29 -04:00
surechen
8750e24247 Fixing span manipulation and indentation of the suggestion introduced by #126187
According to comments:
https://github.com/rust-lang/rust/pull/128084#issuecomment-2295254576
https://github.com/rust-lang/rust/pull/126187/files#r1634897691
2024-08-25 20:30:06 +08:00
Trevor Gross
00308920ae
Rollup merge of #128467 - estebank:unsized-args, r=cjgillot
Detect `*` operator on `!Sized` expression

The suggestion is new:

```
error[E0277]: the size for values of type `str` cannot be known at compilation time
  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:15:9
   |
LL |     let x = *"";
   |         ^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `str`
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature
help: references to `!Sized` types like `&str` are `Sized`; consider not dereferencing the expression
   |
LL -     let x = *"";
LL +     let x = "";
   |
```

Fix #128199.
2024-08-24 21:03:30 -05:00
bors
a60a9e567a Auto merge of #129464 - GuillaumeGomez:rollup-ckfqd7h, r=GuillaumeGomez
Rollup of 9 pull requests

Successful merges:

 - #128511 (Document WebAssembly target feature expectations)
 - #129243 (do not build `cargo-miri` by default on stable channel)
 - #129263 (Add a missing compatibility note in the 1.80.0 release notes)
 - #129276 (Stabilize feature `char_indices_offset`)
 - #129350 (adapt integer comparison tests for LLVM 20 IR changes)
 - #129408 (Fix handling of macro arguments within the `dropping_copy_types` lint)
 - #129426 (rustdoc-search: use tighter json for names and parents)
 - #129437 (Fix typo in a help diagnostic)
 - #129457 (kobzol vacation)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-08-23 10:56:34 +00:00
Guillaume Gomez
09b37855f6
Rollup merge of #129437 - gurry:fix-diagnostic-typo, r=jieyouxu
Fix typo in a help diagnostic

Replaced "**the your** dependency graph" with "**in the** dependency graph".
2024-08-23 12:32:17 +02:00
Matthias Krüger
487b3d92cf
Rollup merge of #129386 - cjgillot:local-resolved-arg, r=compiler-errors
Use a LocalDefId in ResolvedArg.
2024-08-23 06:26:53 +02:00
Gurinder Singh
b544603c03 Fix typo in help diagnostic 2024-08-23 08:21:25 +05:30
bors
8269be147b Auto merge of #129398 - matthiaskrgr:rollup-50l01ry, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #128432 (WASI: forbid `unsafe_op_in_unsafe_fn` for `std::{os, sys}`)
 - #129373 (Add missing module flags for CFI and KCFI sanitizers)
 - #129374 (Use `assert_unsafe_precondition!` in `AsciiChar::digit_unchecked`)
 - #129376 (Change `assert_unsafe_precondition` docs to refer to `check_language_ub`)
 - #129382 (Add `const_cell_into_inner` to `OnceCell`)
 - #129387 (Advise against removing the remaining Python scripts from `tests/run-make`)
 - #129388 (Do not rely on names to find lifetimes.)
 - #129395 (Pretty-print own args of existential projections (dyn-Trait w/ GAT constraints))

r? `@ghost`
`@rustbot` modify labels: rollup
2024-08-22 08:20:49 +00:00
bors
739b1fdb15 Auto merge of #129365 - matthiaskrgr:rollup-ebwx6ya, r=matthiaskrgr
Rollup of 9 pull requests

Successful merges:

 - #127279 (use old ctx if has same expand environment during decode span)
 - #127945 (Implement `debug_more_non_exhaustive`)
 - #128941 ( Improve diagnostic-related lints: `untranslatable_diagnostic` & `diagnostic_outside_of_impl`)
 - #129070 (Point at explicit `'static` obligations on a trait)
 - #129187 (bootstrap: fix clean's remove_dir_all implementation)
 - #129231 (improve submodule updates)
 - #129264 (Update `library/Cargo.toml` in weekly job)
 - #129284 (rustdoc: animate the `:target` highlight)
 - #129302 (compiletest: use `std::fs::remove_dir_all` now that it is available)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-08-22 05:17:27 +00:00
Camille GILLOT
ca7c55f050 Do not rely on names to find lifetimes. 2024-08-22 02:20:05 +00:00
Camille GILLOT
c51f2d24d1 Use a LocalDefId in ResolvedArg. 2024-08-22 01:17:01 +00:00
Esteban Küber
f5bae722be Point at explicit 'static obligations on a trait
Given `trait Any: 'static` and a `struct` with a `Box<dyn Any + 'a>` field, point at the `'static` bound in `Any` to explain why `'a: 'static`.

```
error[E0478]: lifetime bound not satisfied
   --> f202.rs:2:12
    |
2   |     value: Box<dyn std::any::Any + 'a>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
note: lifetime parameter instantiated with the lifetime `'a` as defined here
   --> f202.rs:1:14
    |
1   | struct Hello<'a> {
    |              ^^
note: but lifetime parameter must outlive the static lifetime
   --> /home/gh-estebank/rust/library/core/src/any.rs:113:16
    |
113 | pub trait Any: 'static {
    |                ^^^^^^^
```

Partially address #33652.
2024-08-21 16:40:15 +00:00
Matthias Krüger
4137f3bc15
Rollup merge of #129345 - compiler-errors:scratch4, r=jieyouxu
Use shorthand field initialization syntax more aggressively in the compiler

Caught these when cleaning up #129344 and decided to run clippy to find the rest
2024-08-21 18:15:06 +02:00
Michael Goulet
0b2525c787 Simplify some redundant field names 2024-08-21 01:31:42 -04:00
Michael Goulet
25ff9b6bcb Use bool in favor of Option<()> for diagnostics 2024-08-21 01:31:11 -04:00
bors
a971212545 Auto merge of #127672 - compiler-errors:precise-capturing, r=spastorino
Stabilize opaque type precise capturing (RFC 3617)

This PR partially stabilizes opaque type *precise capturing*, which was specified in [RFC 3617](https://github.com/rust-lang/rfcs/pull/3617), and whose syntax was amended by FCP in [#125836](https://github.com/rust-lang/rust/issues/125836).

This feature, as stabilized here, gives us a way to explicitly specify the generic lifetime parameters that an RPIT-like opaque type captures.  This solves the problem of overcapturing, for lifetime parameters in these opaque types, and will allow the Lifetime Capture Rules 2024 ([RFC 3498](https://github.com/rust-lang/rfcs/pull/3498)) to be fully stabilized for RPIT in Rust 2024.

### What are we stabilizing?

This PR stabilizes the use of a `use<'a, T>` bound in return-position impl Trait opaque types.  Such a bound fully specifies the set of generic parameters captured by the RPIT opaque type, entirely overriding the implicit default behavior.  E.g.:

```rust
fn does_not_capture<'a, 'b>() -> impl Sized + use<'a> {}
//                               ~~~~~~~~~~~~~~~~~~~~
//                This RPIT opaque type does not capture `'b`.
```

The way we would suggest thinking of `impl Trait` types *without* an explicit `use<..>` bound is that the `use<..>` bound has been *elided*, and that the bound is filled in automatically by the compiler according to the edition-specific capture rules.

All non-`'static` lifetime parameters, named (i.e. non-APIT) type parameters, and const parameters in scope are valid to name, including an elided lifetime if such a lifetime would also be valid in an outlives bound, e.g.:

```rust
fn elided(x: &u8) -> impl Sized + use<'_> { x }
```

Lifetimes must be listed before type and const parameters, but otherwise the ordering is not relevant to the `use<..>` bound.  Captured parameters may not be duplicated.  For now, only one `use<..>` bound may appear in a bounds list.  It may appear anywhere within the bounds list.

### How does this differ from the RFC?

This stabilization differs from the RFC in one respect: the RFC originally specified `use<'a, T>` as syntactically part of the RPIT type itself, e.g.:

```rust
fn capture<'a>() -> impl use<'a> Sized {}
```

However, settling on the final syntax was left as an open question.  T-lang later decided via FCP in [#125836](https://github.com/rust-lang/rust/issues/125836) to treat `use<..>` as a syntactic bound instead, e.g.:

```rust
fn capture<'a>() -> impl Sized + use<'a> {}
```

### What aren't we stabilizing?

The key goal of this PR is to stabilize the parts of *precise capturing* that are needed to enable the migration to Rust 2024.

There are some capabilities of *precise capturing* that the RFC specifies but that we're not stabilizing here, as these require further work on the type system.  We hope to lift these limitations later.

The limitations that are part of this PR were specified in the [RFC's stabilization strategy](https://rust-lang.github.io/rfcs/3617-precise-capturing.html#stabilization-strategy).

#### Not capturing type or const parameters

The RFC addresses the overcapturing of type and const parameters; that is, it allows for them to not be captured in opaque types.  We're not stabilizing that in this PR.  Since all in scope generic type and const parameters are implicitly captured in all editions, this is not needed for the migration to Rust 2024.

For now, when using `use<..>`, all in scope type and const parameters must be nameable (i.e., APIT cannot be used) and included as arguments.  For example, this is an error because `T` is in scope and not included as an argument:

```rust
fn test<T>() -> impl Sized + use<> {}
//~^ ERROR `impl Trait` must mention all type parameters in scope in `use<...>`
```

This is due to certain current limitations in the type system related to how generic parameters are represented as captured (i.e. bivariance) and how inference operates.

We hope to relax this in the future, and this stabilization is forward compatible with doing so.

#### Precise capturing for return-position impl Trait **in trait** (RPITIT)

The RFC specifies precise capturing for RPITIT.  We're not stabilizing that in this PR.  Since RPITIT already adheres to the Lifetime Capture Rules 2024, this isn't needed for the migration to Rust 2024.

The effect of this is that the anonymous associated types created by RPITITs must continue to capture all of the lifetime parameters in scope, e.g.:

```rust
trait Foo<'a> {
    fn test() -> impl Sized + use<Self>;
    //~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
}
```

To allow this involves a meaningful amount of type system work related to adding variance to GATs or reworking how generics are represented in RPITITs.  We plan to do this work separately from the stabilization.  See:

- https://github.com/rust-lang/rust/pull/124029

Supporting precise capturing for RPITIT will also require us to implement a new algorithm for detecting refining capture behavior.  This may involve looking through type parameters to detect cases where the impl Trait type in an implementation captures fewer lifetimes than the corresponding RPITIT in the trait definition, e.g.:

```rust
trait Foo {
    fn rpit() -> impl Sized + use<Self>;
}

impl<'a> Foo for &'a () {
    // This is "refining" due to not capturing `'a` which
    // is implied by the trait's `use<Self>`.
    fn rpit() -> impl Sized + use<>;

    // This is not "refining".
    fn rpit() -> impl Sized + use<'a>;
}
```

This stabilization is forward compatible with adding support for this later.

### The technical details

This bound is purely syntactical and does not lower to a [`Clause`](https://doc.rust-lang.org/1.79.0/nightly-rustc/rustc_middle/ty/type.ClauseKind.html) in the type system.  For the purposes of the type system (and for the types team's curiosity regarding this stabilization), we have no current need to represent this as a `ClauseKind`.

Since opaques already capture a variable set of lifetimes depending on edition and their syntactical position (e.g. RPIT vs RPITIT), a `use<..>` bound is just a way to explicitly rather than implicitly specify that set of lifetimes, and this only affects opaque type lowering from AST to HIR.

### FCP plan

While there's much discussion of the type system here, the feature in this PR is implemented internally as a transformation that happens before lowering to the type system layer.  We already support impl Trait types partially capturing the in scope lifetimes; we just currently only expose that implicitly.

So, in my (errs's) view as a types team member, there's nothing for types to weigh in on here with respect to the implementation being stabilized, and I'd suggest a lang-only proposed FCP (though we'll of course CC the team below).

### Authorship and acknowledgments

This stabilization report was coauthored by compiler-errors and TC.

TC would like to acknowledge the outstanding and speedy work that compiler-errors has done to make this feature happen.

compiler-errors thanks TC for authoring the RFC, for all of his involvement in this feature's development, and pushing the Rust 2024 edition forward.

### Open items

We're doing some things in parallel here.  In signaling the intention to stabilize, we want to uncover any latent issues so we can be sure they get addressed.  We want to give the maximum time for discussion here to happen by starting it while other remaining miscellaneous work proceeds.  That work includes:

- [x] Look into `syn` support.
  - https://github.com/dtolnay/syn/issues/1677
  - https://github.com/dtolnay/syn/pull/1707
- [x] Look into `rustfmt` support.
  - https://github.com/rust-lang/rust/pull/126754
- [x] Look into `rust-analyzer` support.
  - https://github.com/rust-lang/rust-analyzer/issues/17598
  - https://github.com/rust-lang/rust-analyzer/pull/17676
- [x] Look into `rustdoc` support.
  - https://github.com/rust-lang/rust/issues/127228
  - https://github.com/rust-lang/rust/pull/127632
  - https://github.com/rust-lang/rust/pull/127658
- [x] Suggest this feature to RfL (a known nightly user).
- [x] Add a chapter to the edition guide.
  - https://github.com/rust-lang/edition-guide/pull/316
- [x] Update the Reference.
  - https://github.com/rust-lang/reference/pull/1577

### (Selected) implementation history

* https://github.com/rust-lang/rfcs/pull/3498
* https://github.com/rust-lang/rfcs/pull/3617
* https://github.com/rust-lang/rust/pull/123468
* https://github.com/rust-lang/rust/issues/125836
* https://github.com/rust-lang/rust/pull/126049
* https://github.com/rust-lang/rust/pull/126753

Closes #123432.

cc `@rust-lang/lang` `@rust-lang/types`

`@rustbot` labels +T-lang +I-lang-nominated +A-impl-trait +F-precise_capturing

Tracking:

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

----

For the compiler reviewer, I'll leave some inline comments about diagnostics fallout :^)

r? compiler
2024-08-20 10:42:55 +00:00
Veera
12de141df2 Suggest impl Trait for References to Bare Trait in Function Header 2024-08-19 15:19:43 -04:00
Matthias Krüger
5cb30b7e9d
Rollup merge of #129217 - jswrenn:transmute-lifetimes, r=compiler-errors
safe transmute: check lifetimes

Modifies `BikeshedIntrinsicFrom` to forbid lifetime extensions on references. This static check can be opted out of with the `Assume::lifetimes` flag.

Fixes #129097

Tracking Issue: https://github.com/rust-lang/rust/issues/99571

 r​? `@compiler-errors`
2024-08-19 20:14:56 +02:00
Trevor Gross
8a513f1720
Rollup merge of #129208 - veluca93:adt_const_fix, r=BoxyUwU
Fix order of normalization and recursion in const folding.

Fixes #126831.

Without this patch, type normalization is not always idempotent, which leads to all sorts of bugs in places that assume that normalizing a normalized type does nothing.

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

r? BoxyUwU
2024-08-18 23:41:49 -05:00
Trevor Gross
d21b6f2715
Rollup merge of #128084 - surechen:fix_125997_v1, r=cjgillot
Suggest adding Result return type for associated method in E0277.

Recommit #126515 because I messed up during rebase,

Suggest adding Result return type for associated method in E0277.

For following:

```rust
struct A;
impl A {
    fn test4(&self) {
        let mut _file = File::create("foo.txt")?;
        //~^ ERROR the `?` operator can only be used in a method
    }
```

Suggest:

```rust
impl A {
    fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
        let mut _file = File::create("foo.txt")?;
        //~^ ERROR the `?` operator can only be used in a method

    Ok(())
    }
}
```

For #125997

r? `@cjgillot`
2024-08-18 23:41:46 -05:00
Jack Wrenn
17995d5cc2 safe transmute: forbid reference lifetime extension
Modifies `BikeshedIntrinsicFrom` to forbid lifetime extensions on
references. This static check can be opted out of with the
`Assume::lifetimes` flag.

Fixes #129097
2024-08-18 18:31:06 +00:00
许杰友 Jieyou Xu (Joe)
130cb9e30c
Rollup merge of #129203 - compiler-errors:extern_crate_data, r=jieyouxu
Use cnum for extern crate data key

Noticed this when fixing #129184. I still have yet to put up a fix for that (mostly because I'm too lazy to minimize a test, that will come soon though).
2024-08-18 14:55:23 +08:00
Luca Versari
7fd62320fe Fix order of normalization and recursion in const folding.
Fixes #126831.

Without this patch, type normalization is not always idempotent, which
leads to all sorts of bugs in places that assume that normalizing a
normalized type does nothing.
2024-08-18 00:07:41 +02:00
bors
feeba198f2 Auto merge of #128792 - compiler-errors:foreign-sig, r=spastorino
Use `FnSig` instead of raw `FnDecl` for `ForeignItemKind::Fn`, fix ICE for `Fn` trait error on safe foreign fn

Let's use `hir::FnSig` instead of `hir::FnDecl + hir::Safety` for `ForeignItemKind::Fn`. This consolidates some handling code between normal fns and foreign fns.

Separetly, fix an ICE where we weren't handling `Fn` trait errors for safe foreign fns.

If perf is bad for the first commit, I can rework the ICE fix to not rely on it. But if perf is good, I prefer we fix and clean up things all at once 👍

r? spastorino

Fixes #128764
2024-08-17 19:35:01 +00:00
Michael Goulet
b2dd943d4b Use cnum for extern crate data 2024-08-17 12:50:18 -04:00
Michael Goulet
84044cd50f Bless test fallout 2024-08-17 12:43:25 -04:00
bors
9b318d2e93 Auto merge of #128786 - estebank:multiple-crate-versions, r=fee1-dead
Detect multiple crate versions on method not found

When a type comes indirectly from one crate version but the imported trait comes from a separate crate version, the called method won't be found. We now show additional context:

```
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
 --> multiple-dep-versions.rs:8:10
  |
8 |     Type.foo();
  |          ^^^ method not found in `Type`
  |
note: there are multiple different versions of crate `dependency` in the dependency graph
 --> multiple-dep-versions.rs:4:32
  |
4 | use dependency::{do_something, Trait};
  |                                ^^^^^ `dependency` imported here doesn't correspond to the right crate version
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-1.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that was imported
  |
 ::: ~/rust/build/x86_64-unknown-linux-gnu/test/run-make/crate-loading/rmake_out/multiple-dep-versions-2.rs:4:1
  |
4 | pub trait Trait {
  | --------------- this is the trait that is needed
5 |     fn foo(&self);
  |        --- the method is available for `dep_2_reexport::Type` here
```

Fix #128569, fix #110926, fix #109161, fix #81659, fix #51458, fix #32611. Follow up to #124944.
2024-08-17 14:40:04 +00:00
Michael Goulet
d850f85055 Don't ICE on Fn trait error for foreign fn 2024-08-16 14:10:06 -04:00
Jubilee
4f46643698
Rollup merge of #129078 - lcnr:scrape_region_constraints-use-ocx, r=compiler-errors
`ParamEnvAnd::fully_perform`: we have an `ocx`, use it

cc #123669

r? ``@compiler-errors``
2024-08-15 18:44:18 -07:00
Matthias Krüger
f3df807207
Rollup merge of #129106 - compiler-errors:unused-type-ops, r=jieyouxu
Remove redundant type ops: `Eq`/`Subtype`

r? lcnr or anyone really
2024-08-15 19:32:37 +02:00
Michael Goulet
f264e5d011 Remove redundant type ops 2024-08-14 14:18:17 -04:00
许杰友 Jieyou Xu (Joe)
59ad2aec49
Rollup merge of #128828 - lcnr:search-graph-11, r=compiler-errors
`-Znext-solver` caching

This PR has two major changes while also fixing multiple issues found via fuzzing.

The main optimization is the ability to not discard provisional cache entries when popping the highest cycle head the entry depends on. This fixes the hang in Fuchsia with `-Znext-solver=coherence`.

It also bails if the result of a fixpoint iteration is ambiguous, even without reaching a fixpoint. This is necessary to avoid exponential blowup if a coinductive cycle results in ambiguity, e.g. due to unknowable candidates in coherence.

Updating stack entries pretty much exclusively happens lazily now, so `fn check_invariants` ended up being mostly useless and I've removed it. See https://gist.github.com/lcnr/8de338fdb2685581e17727bbfab0622a for the invariants we would be able to assert with it.

For a general overview, see the in-process update of the relevant rustc-dev-guide chapter: https://hackmd.io/1ALkSjKlSCyQG-dVb_PUHw

r? ```@compiler-errors```
2024-08-14 21:43:07 +08:00
lcnr
3a02047d52 if we have an ocx, use it 2024-08-14 09:36:53 +02:00
bors
9859bf27fd Auto merge of #129076 - matthiaskrgr:rollup-rg8mi2x, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #128410 (Migrate `remap-path-prefix-dwarf` `run-make` test to rmake)
 - #128759 (alloc: add ToString specialization for `&&str`)
 - #128873 (Add windows-targets crate to std's sysroot)
 - #129001 (chore(lib): Enhance documentation for core::fmt::Formatter's write_fm…)
 - #129061 (Use `is_lang_item` more)
 - #129062 (Remove a no-longer-true assert)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-08-14 04:17:13 +00:00
Matthias Krüger
cd6852b9ea
Rollup merge of #129061 - compiler-errors:lang-item, r=Urgau
Use `is_lang_item` more

Few places that I missed since introducing `TyCtxt::is_lang_item`.
2024-08-14 05:05:52 +02:00
Matthias Krüger
85180cd365
Rollup merge of #128759 - notriddle:notriddle/spec-to-string, r=workingjubilee,compiler-errors
alloc: add ToString specialization for `&&str`

Fixes #128690
2024-08-14 05:05:51 +02:00
bors
e9c965df7b Auto merge of #128812 - nnethercote:shrink-TyKind-FnPtr, r=compiler-errors
Shrink `TyKind::FnPtr`.

By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and `FnHeader`, which can be packed more efficiently. This reduces the size of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms. This reduces peak memory usage by a few percent on some benchmarks. It also reduces cache misses and page faults similarly, though this doesn't translate to clear cycles or wall-time improvements on CI.

r? `@compiler-errors`
2024-08-14 00:56:53 +00:00
Michael Goulet
bac19686a5 Use is_lang_item more 2024-08-13 16:44:53 -04:00
Michael Howell
c6fb0f344e diagnostics: use DeepRejectCtxt for check
This makes more things match, particularly applicable blankets.
2024-08-13 10:01:13 -07:00
Matthias Krüger
85eb465a10
Rollup merge of #128912 - compiler-errors:do-not-recommend-impl, r=lcnr
Store `do_not_recommend`-ness in impl header

Alternative to #128674

It's less flexible, but also less invasive. Hopefully it's also performant. I'd recommend we think separately about the design for how to gate arbitrary diagnostic attributes moving forward.
2024-08-12 23:10:51 +02:00
Matthias Krüger
4c49418472
Rollup merge of #128712 - compiler-errors:normalize-borrowck, r=lcnr
Normalize struct tail properly for `dyn` ptr-to-ptr casting in new solver

Realized that the new solver didn't handle ptr-to-ptr casting correctly.

r? lcnr

Built on #128694
2024-08-12 23:10:50 +02:00
Esteban Küber
5c427b4600 reword message 2024-08-12 19:29:47 +00:00
Guillaume Gomez
7c6dca9050
Rollup merge of #128978 - compiler-errors:assert-matches, r=jieyouxu
Use `assert_matches` around the compiler more

It's a useful assertion, especially since it actually prints out the LHS.
2024-08-12 17:09:19 +02:00
lcnr
7b86c98068 do not use the global solver cache for proof trees
doing so requires overwriting global cache entries and
generally adds significant complexity to the solver. This is
also only ever done for root goals, so it feels easier to wrap
the `evaluate_canonical_goal` in an ordinary query if
necessary.
2024-08-12 10:33:04 +02:00
Michael Goulet
f15997ffec Remove struct_tail_no_normalization 2024-08-11 19:40:03 -04:00
Michael Goulet
b5d2079fb9 Rename normalization functions to raw 2024-08-11 19:40:03 -04:00
Michael Goulet
c361c924a0 Use assert_matches around the compiler 2024-08-11 12:25:39 -04:00
Matthias Krüger
32e0fe129d
Rollup merge of #128762 - fmease:use-more-slice-pats, r=compiler-errors
Use more slice patterns inside the compiler

Nothing super noteworthy. Just replacing the common 'fragile' pattern of "length check followed by indexing or unwrap" with slice patterns for legibility and 'robustness'.

r? ghost
2024-08-11 07:51:51 +02:00
bors
48090b11b5 Auto merge of #128746 - compiler-errors:cache-super-outlives, r=lcnr
Cache supertrait outlives of impl header for soundness check

This caches the results of computing the transitive supertraits of an impl and filtering it to its outlives obligations. This is purely an optimization to improve https://github.com/rust-lang/rust/pull/124336.
2024-08-10 10:22:06 +00:00
Michael Goulet
ed7bdbb17b Store do_not_recommend-ness in impl header 2024-08-09 22:02:20 -04:00
Nicholas Nethercote
c4717cc9d1 Shrink TyKind::FnPtr.
By splitting the `FnSig` within `TyKind::FnPtr` into `FnSigTys` and
`FnHeader`, which can be packed more efficiently. This reduces the size
of the hot `TyKind` type from 32 bytes to 24 bytes on 64-bit platforms.
This reduces peak memory usage by a few percent on some benchmarks. It
also reduces cache misses and page faults similarly, though this doesn't
translate to clear cycles or wall-time improvements on CI.
2024-08-09 14:33:25 +10:00
Matthias Krüger
bcf6f9fa76
Rollup merge of #128791 - compiler-errors:async-fn-unsafe, r=lcnr
Don't implement `AsyncFn` for `FnDef`/`FnPtr` that wouldnt implement `Fn`

Due to unsafety, ABI, or the presence of target features, some `FnDef`/`FnPtr` types don't implement `Fn*`. Do the same for `AsyncFn*`.

Noticed this due to #128764, but this isn't really related to that ICE, which is fixed in #128792.
2024-08-09 00:03:36 +02:00
Michael Goulet
ec1c424293 Don't implement AsyncFn for FnDef/FnPtr that wouldnt implement Fn 2024-08-08 14:07:31 -04:00
Esteban Küber
f6767f7a68 Detect * operator on !Sized expression
```
error[E0277]: the size for values of type `str` cannot be known at compilation time
  --> $DIR/unsized-str-in-return-expr-arg-and-local.rs:15:9
   |
LL |     let x = *"";
   |         ^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `str`
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
   |
LL -     let x = *"";
LL +     let x = "";
   |
```
2024-08-08 17:35:40 +00:00
Guillaume Gomez
493233ce29
Rollup merge of #128527 - estebank:ambiguity-suggestion, r=Nadrieril
More information for fully-qualified suggestion when there are multiple impls

```
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
  --> $DIR/E0283.rs:30:21
   |
LL |     fn create() -> u32;
   |     ------------------- `Coroutine::create` defined here
...
LL |     let cont: u32 = Coroutine::create();
   |                     ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
   |
help: use a fully-qualified path to a specific available implementation
   |
LL |     let cont: u32 = <Impl as Coroutine>::create();
   |                     ++++++++          +
LL |     let cont: u32 = <AnotherImpl as Coroutine>::create();
   |                     +++++++++++++++          +
```
2024-08-07 15:59:36 +02:00
León Orell Valerian Liehr
c4c518d2d4
Use more slice patterns inside the compiler 2024-08-07 13:37:52 +02:00
Michael Howell
20c833c632 diagnostics: Box<dyn Trait> suggestion with multiple matching impl
The two altered expectation messages both seem like improvements:

- `coerce-expect-unsized-ascribed.stderr` says you can go
  `Box<char> -> Box<dyn Debug>`, which you can.
- `upcast_soundness_bug.stderr` used to say that you could go
  `Box<dyn Trait<u8, u8>> -> Box<dyn Trait>`, which you can't,
  because the type parameters are missing in the destination
  and the only ones that work aren't what's needed.
2024-08-06 18:24:17 -07:00
Esteban Küber
edd4162393 fix rebase 2024-08-06 17:54:39 +00:00
Esteban Küber
d8b07718f4 Add help about using cargo tree 2024-08-06 17:54:39 +00:00
Esteban Küber
4868680ee9 On trait bound mismatch, detect multiple crate versions in dep tree
When encountering an E0277, if the type and the trait both come from a crate with the same name but different crate number, we explain that there are multiple crate versions in the dependency tree.

If there's a type that fulfills the bound, and it has the same name as the passed in type and has the same crate name, we explain that the same type in two different versions of the same crate *are different*.

```
error[E0277]: the trait bound `Type: dependency::Trait` is not satisfied
 --> src/main.rs:4:18
  |
4 |     do_something(Type);
  |     ------------ ^^^^ the trait `dependency::Trait` is not implemented for `Type`
  |     |
  |     required by a bound introduced by this call
  |
help: you have multiple different versions of crate `dependency` in your dependency graph
 --> src/main.rs:1:5
  |
1 | use bar::do_something;
  |     ^^^ one version of crate `dependency` is used here, as a dependency of crate `bar`
2 | use dependency::Type;
  |     ^^^^^^^^^^ one version of crate `dependency` is used here, as a direct dependency of the current crate
note: two types coming from two different versions of the same crate are different types even if they look the same
 --> /home/gh-estebank/crate_versions/baz-2/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type doesn't implement the required trait
  |
 ::: /home/gh-estebank/crate_versions/baz/src/lib.rs:1:1
  |
1 | pub struct Type;
  | ^^^^^^^^^^^^^^^ this type implements the required trait
2 | pub trait Trait {}
  | --------------- this is the required trait
note: required by a bound in `bar::do_something`
 --> /home/gh-estebank/crate_versions/baz/src/lib.rs:4:24
  |
4 | pub fn do_something<X: Trait>(_: X) {}
  |                        ^^^^^ required by this bound in `do_something`
```

Address #22750.
2024-08-06 17:54:39 +00:00
Michael Goulet
79228526bf Cache supertrait outlives of impl header for soundness check 2024-08-06 13:33:32 -04:00
bors
f7eefec4e0 Auto merge of #128689 - matthiaskrgr:rollup-ukyn8wq, r=matthiaskrgr
Rollup of 5 pull requests

Successful merges:

 - #128385 (rustdoc-json: discard non-local inherent impls for primitives)
 - #128559 (Don't re-elaborated already elaborated caller bounds in method probe)
 - #128631 (handle crates when they are not specified for std docs)
 - #128664 (Add `Debug` impls to API types in `rustc_codegen_ssa`)
 - #128686 (fix the invalid argument type)

r? `@ghost`
`@rustbot` modify labels: rollup
2024-08-05 17:03:58 +00:00
Michael Goulet
34e087890c Don't re-elaborated already elaborated caller bounds in method probe 2024-08-05 10:48:20 -04:00
Michael Goulet
fa9ae7b9d3 Elaborate supertraits in dyn candidates 2024-08-05 10:03:17 -04:00
Michael Goulet
6a891ec4fe Enforce supertrait outlives obligations hold when confirming impl 2024-08-05 09:55:14 -04:00
Esteban Küber
2c83c99058 More information for fully-qualified suggestion when there are multiple impls
```
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
  --> $DIR/E0283.rs:30:21
   |
LL |     fn create() -> u32;
   |     ------------------- `Coroutine::create` defined here
...
LL |     let cont: u32 = Coroutine::create();
   |                     ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
   |
help: use a fully-qualified path to a specific available implementation
   |
LL |     let cont: u32 = <Impl as Coroutine>::create();
   |                     ++++++++          +
LL |     let cont: u32 = <AnotherImpl as Coroutine>::create();
   |                     +++++++++++++++          +
```
2024-08-02 03:22:56 +00:00
Matthias Krüger
b22c48ed6e
Rollup merge of #128438 - Bryanskiy:empty-array-dropck, r=lcnr
Add special-case for [T, 0] in dropck_outlives

implements/fixes #110288.

r? `@lcnr`
2024-07-31 23:20:12 +02:00
Bryanskiy
34fcf92ea0 Add special-case for [T, 0] in dropck 2024-07-31 16:15:05 +03:00
bors
f8060d282d Auto merge of #128083 - Mark-Simulacrum:bump-bootstrap, r=albertlarsan68
Bump bootstrap compiler to new beta

https://forge.rust-lang.org/release/process.html#master-bootstrap-update-t-2-day-tuesday
2024-07-30 17:49:08 +00:00
bohan
97469cc4bf only accept adt type during infer source visitor 2024-07-29 22:29:34 +08:00
Nicholas Nethercote
84ac80f192 Reformat use declarations.
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
2024-07-29 08:26:52 +10:00
Mark Rousskov
5eca36d27a step cfg(bootstrap) 2024-07-28 14:46:29 -04:00
Trevor Gross
bd18f88dab
Rollup merge of #128201 - compiler-errors:closure-clone, r=oli-obk
Implement `Copy`/`Clone` for async closures

We can do so in the same cases that regular closures do.

For the purposes of cloning, coroutine-closures are actually precisely the same as regular closures, specifically in the aspect that `Clone` impls care about which is the upvars. The only difference b/w coroutine-closures and regular closures is the type that they *return*, but this type has not been *created* yet, so we don't really have a problem.

IDK why I didn't add this impl initially -- I went back and forth a bit on the internal representation for coroutine-closures before settling on a design which largely models regular closures. Previous (not published) iterations of coroutine-closures used to be represented as a special (read: cursed) kind of coroutine, which would probably suffer from the pitfalls that coroutines have that oli mentioned below in https://github.com/rust-lang/rust/pull/128201#issuecomment-2251230274.

r? oli-obk
2024-07-26 19:03:05 -04:00
bors
7c2012d0ec Auto merge of #121676 - Bryanskiy:polarity, r=petrochenkov
Support ?Trait bounds in supertraits and dyn Trait under a feature gate

This patch allows `maybe` polarity bounds under a feature gate. The only language change here is that corresponding hard errors are replaced by feature gates. Example:
```rust
#![feature(allow_maybe_polarity)]
...
trait Trait1 : ?Trait { ... } // ok
fn foo(_: Box<(dyn Trait2 + ?Trait)>) {} // ok
fn bar<T: ?Sized + ?Trait>(_: &T) {} // ok
```
Maybe bounds still don't do anything (except for `Sized` trait), however this patch will allow us to [experiment with default auto traits](https://github.com/rust-lang/rust/pull/120706#issuecomment-1934006762).

This is a part of the [MCP: Low level components for async drop](https://github.com/rust-lang/compiler-team/issues/727)
2024-07-26 20:14:16 +00:00
Michael Goulet
d5656059a1 Make coroutine-closures possible to be cloned 2024-07-26 12:53:53 -04:00
Matthias Krüger
a88354831b
Rollup merge of #126090 - compiler-errors:supertrait-assoc-ty-unsoundness, r=lcnr
Fix supertrait associated type unsoundness

### What?

Object safety allows us to name `Self::Assoc` associated types in certain positions if they come from our trait or one of our supertraits. When this check was implemented, I think it failed to consider that supertraits can have different args, and it was only checking def-id equality.

This is problematic, since we can sneak different implementations in by implementing `Supertrait<NotActuallyTheSupertraitSubsts>` for a `dyn` type. This can be used to implement an unsound transmute function. See the committed test.

### How do we fix it?

We consider the whole trait ref when checking for supertraits. Right now, this is implemented using equality *without* normalization. We erase regions since those don't affect trait selection.

This is a limitation that could theoretically affect code that should be accepted, but doesn't matter in practice -- there are 0 crater regression. We could make this check stronger, but I would be worried about cycle issues. I assume that most people are writing `Self::Assoc` so they don't really care about the trait ref being normalized.

---

### What is up w the stacked commit

This is built on top of https://github.com/rust-lang/rust/pull/122804 though that's really not related, it's just easier to make this modification with the changes to the object safety code that I did in that PR. The only thing is that PR may make this unsoundness slightly easier to abuse, since there are more positions that allow self-associated-types -- I am happy to stall that change until this PR merges.

---

Fixes #126079

r? lcnr
2024-07-26 00:57:20 +02:00
Bryanskiy
2a73553513 Support ?Trait bounds in supertraits and dyn Trait under a feature gate 2024-07-25 20:53:33 +03:00
Matthias Krüger
1fda084290
Rollup merge of #128160 - compiler-errors:auto, r=jackh726
Don't ICE when auto trait has assoc ty in old solver

Kinda a pointless change to make, but it's observable w/o the feature gate, so let's just fix it. I reintroduced this ICE when I removed the "auto impl" kind from `ImplSource` in #112687.

Fixes #117829
Fixes #127746
2024-07-25 04:43:20 +02:00
Michael Goulet
0919d0714e Don't ICE when auto trait has assoc ty in old solver 2024-07-24 17:19:44 -04:00
Oli Scherer
8ea461da55 Do not assemble candidates for auto traits of opaque types in their defining scope 2024-07-24 16:00:48 +00:00
Oli Scherer
acba6449f8 Do not try to reveal hidden types when trying to prove Freeze in the defining scope 2024-07-24 16:00:48 +00:00
Oli Scherer
61b5e11c47 Don't use global caches if opaques can be defined 2024-07-24 10:45:21 +00:00
Matthias Krüger
004d1adc5d
Rollup merge of #128076 - compiler-errors:infer_ctxt_ext, r=lcnr
Get rid of `InferCtxtExt` from `error_reporting::traits`

One more cleanup.

r? lcnr
2024-07-23 13:06:56 +02:00
surechen
b4b991e66f Suggest adding Result return type for associated method in E0277.
For following:

```rust
struct A;
impl A {
    fn test4(&self) {
        let mut _file = File::create("foo.txt")?;
        //~^ ERROR the `?` operator can only be used in a method
    }
```
Suggest:

```rust
impl A {
    fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
        let mut _file = File::create("foo.txt")?;
        //~^ ERROR the `?` operator can only be used in a method

    Ok(())
    }
}
```

For #125997
2024-07-23 10:24:45 +08:00
Michael Goulet
6310e40578 Get rid of infer_ctxt_ext 2024-07-22 16:15:52 -04:00
Michael Goulet
7bca516b35 Get rid of can_eq_shallow 2024-07-22 13:54:48 -04:00
Michael Goulet
e9e9495f21 Fix tools 2024-07-21 22:34:37 -04:00
Michael Goulet
ce8a625092 Move all error reporting into rustc_trait_selection 2024-07-21 22:34:35 -04:00
Michael Goulet
f49738ba6c Move need_type_info too 2024-07-21 22:33:15 -04:00
bors
9629b90b3f Auto merge of #127722 - BoxyUwU:new_adt_const_params_limitations, r=compiler-errors
Forbid borrows and unsized types from being used as the type of a const generic under `adt_const_params`

Fixes #112219
Fixes #112124
Fixes #112125

### Motivation

Currently the `adt_const_params` feature allows writing `Foo<const N: [u8]>` this is entirely useless as it is not possible to write an expression which evaluates to a type that is not `Sized`. In order to actually use unsized types in const generics they are typically written as `const N: &[u8]` which *is* possible to provide a value of.

Unfortunately allowing the types of const parameters to contain references is non trivial (#120961) as it introduces a number of difficult questions about how equality of references in the type system should behave. References in the types of const generics is largely only useful for using unsized types in const generics.

This PR introduces a new feature gate `unsized_const_parameters` and moves support for `const N: [u8]` and `const N: &...` from `adt_const_params` into it. The goal here hopefully is to experiment with allowing `const N: [u8]` to work without references and then eventually completely forbid references in const generics.

Splitting this out into a new feature gate means that stabilization of `adt_const_params` does not have to resolve #120961 which is the only remaining "big" blocker for the feature. Remaining issues after this are a few ICEs and naming bikeshed for `ConstParamTy`.

### Implementation

The implementation is slightly subtle here as we would like to ensure that a stabilization of `adt_const_params` is forwards compatible with any outcome of `unsized_const_parameters`. This is inherently tricky as we do not support unstable trait implementations and we determine whether a type is valid as the type of a const parameter via a trait bound.

There are a few constraints here:
- We would like to *allow for the possibility* of adding a `Sized` supertrait to `ConstParamTy` in the event that we wind up opting to not support unsized types and instead requiring people to write the 'sized version', e.g. `const N: [u8; M]` instead of `const N: [u8]`.
- Crates should be able to enable `unsized_const_parameters` and write trait implementations of `ConstParamTy` for `!Sized` types without downstream crates that only enable `adt_const_params` being able to observe this (required for std to be able to `impl<T> ConstParamTy for [T]`

Ultimately the way this is accomplished is via having two traits (sad), `ConstParamTy` and `UnsizedConstParamTy`. Depending on whether `unsized_const_parameters` is enabled or not we change which trait is used to check whether a type is allowed to be a const parameter.

Long term (when stabilizing `UnsizedConstParamTy`) it should be possible to completely merge these traits (and derive macros), only having a single `trait ConstParamTy` and `macro ConstParamTy`.

Under `adt_const_params` it is now illegal to directly refer to `ConstParamTy` it is only used as an internal impl detail by `derive(ConstParamTy)` and checking const parameters are well formed. This is necessary in order to ensure forwards compatibility with all possible future directions for `feature(unsized_const_parameters)`.

Generally the intuition here should be that `ConstParamTy` is the stable trait that everything uses, and `UnsizedConstParamTy` is that plus unstable implementations (well, I suppose `ConstParamTy` isn't stable yet :P).
2024-07-21 05:36:21 +00:00
Matthias Krüger
89798e9064
Rollup merge of #127987 - estebank:impl-trait-sugg, r=cjgillot
More accurate suggestion for `-> Box<dyn Trait>` or `-> impl Trait`

When encountering `-> Trait`, suggest `-> Box<dyn Trait>` (instead of `-> Box<Trait>`.

If there's a single returned type within the `fn`, suggest `-> impl Trait`.
2024-07-20 07:13:46 +02:00
Esteban Küber
3ff758877f More accurate suggestion for -> Box<dyn Trait> or -> impl Trait
When encountering `-> Trait`, suggest `-> Box<dyn Trait>` (instead of `-> Box<Trait>`.

If there's a single returned type within the `fn`, suggest `-> impl Trait`.
2024-07-19 19:39:37 +00:00
Matthias Krüger
9f8c618a90
Rollup merge of #127856 - RalfJung:interpret-cast-sanity, r=oli-obk
interpret: add sanity check in dyn upcast to double-check what codegen does

For dyn receiver calls, we already have two codepaths: look up the function to call by indexing into the vtable, or alternatively resolve the DefId given the dynamic type of the receiver. With debug assertions enabled, the interpreter does both and compares the results. (Without debug assertions we always use the vtable as it is simpler.)

This PR does the same for dyn trait upcasts. However, for casts *not* using the vtable is the easier thing to do, so now the vtable path is the debug-assertion-only path. In particular, there are cases where the vtable does not contain a pointer for upcasts but instead reuses the old pointer: when the supertrait vtable is a prefix of the larger vtable. We don't want to expose this optimization and detect UB if people do a transmute assuming this optimization, so we cannot in general use the vtable indexing path.

r? ``@oli-obk``
2024-07-19 17:06:50 +02:00
bors
8c3a94a1c7 Auto merge of #125915 - camelid:const-arg-refactor, r=BoxyUwU
Represent type-level consts with new-and-improved `hir::ConstArg`

### Summary

This is a step toward `min_generic_const_exprs`. We now represent all const
generic arguments using an enum that differentiates between const *paths*
(temporarily just bare const params) and arbitrary anon consts that may perform
computations. This will enable us to cleanly implement the `min_generic_const_args`
plan of allowing the use of generics in paths used as const args, while
disallowing their use in arbitrary anon consts. Here is a summary of the salient
aspects of this change:

- Add `current_def_id_parent` to `LoweringContext`

  This is needed to track anon const parents properly once we implement
  `ConstArgKind::Path` (which requires moving anon const def-creation
  outside of `DefCollector`).

- Create `hir::ConstArgKind` enum with `Path` and `Anon` variants. Use it in the
  existing `hir::ConstArg` struct, replacing the previous `hir::AnonConst` field.

- Use `ConstArg` for all instances of const args. Specifically, use it instead
  of `AnonConst` for assoc item constraints, array lengths, and const param
  defaults.

- Some `ast::AnonConst`s now have their `DefId`s created in
  rustc_ast_lowering rather than `DefCollector`. This is because in some
  cases they will end up becoming a `ConstArgKind::Path` instead, which
  has no `DefId`. We have to solve this in a hacky way where we guess
  whether the `AnonConst` could end up as a path const since we can't
  know for sure until after name resolution (`N` could refer to a free
  const or a nullary struct). If it has no chance as being a const
  param, then we create a `DefId` in `DefCollector` -- otherwise we
  decide during ast_lowering. This will have to be updated once all path
  consts use `ConstArgKind::Path`.

- We explicitly use `ConstArgHasType` for array lengths, rather than
  implicitly relying on anon const type feeding -- this is due to the
  addition of `ConstArgKind::Path`.

- Some tests have their outputs changed, but the changes are for the
  most part minor (including removing duplicate or almost-duplicate
  errors). One test now ICEs, but it is for an incomplete, unstable
  feature and is now tracked at https://github.com/rust-lang/rust/issues/127009.

### Followup items post-merge

- Use `ConstArgKind::Path` for all const paths, not just const params.
- Fix (no github dont close this issue) #127009
- If a path in generic args doesn't resolve as a type, try to resolve as a const
  instead (do this in rustc_resolve). Then remove the special-casing from
  `rustc_ast_lowering`, so that all params will automatically be lowered as
  `ConstArgKind::Path`.
- (?) Consider making `const_evaluatable_unchecked` a hard error, or at least
  trying it in crater

r? `@BoxyUwU`
2024-07-19 08:44:51 +00:00
Michael Goulet
8dbb63a585 Remove tag field from relations 2024-07-18 14:34:05 -04:00
Ralf Jung
e613bc92a1 const_to_pat: cleanup leftovers from when we had to deal with non-structural constants 2024-07-18 11:58:16 +02:00
Ralf Jung
fa74a9e6aa valtree construction: keep track of which type was valtree-incompatible 2024-07-18 11:58:16 +02:00
Ralf Jung
a7b80819e9 interpret: add sanity check in dyn upcast to double-check what codegen does 2024-07-18 11:41:10 +02:00
Michael Goulet
0b5ce54bc2 Fix relations 2024-07-17 10:46:10 -04:00
Boxy
d0c11bf6e3 Split part of adt_const_params into unsized_const_params 2024-07-17 11:01:29 +01:00
Boxy
42cc42b942 Forbid !Sized types and references 2024-07-17 11:01:29 +01:00
Noah Lev
37ed7a4438 Add ConstArgKind::Path and make ConstArg its own HIR node
This is a very large commit since a lot needs to be changed in order to
make the tests pass. The salient changes are:

- `ConstArgKind` gets a new `Path` variant, and all const params are now
  represented using it. Non-param paths still use `ConstArgKind::Anon`
  to prevent this change from getting too large, but they will soon use
  the `Path` variant too.

- `ConstArg` gets a distinct `hir_id` field and its own variant in
  `hir::Node`. This affected many parts of the compiler that expected
  the parent of an `AnonConst` to be the containing context (e.g., an
  array repeat expression). They have been changed to check the
  "grandparent" where necessary.

- Some `ast::AnonConst`s now have their `DefId`s created in
  rustc_ast_lowering rather than `DefCollector`. This is because in some
  cases they will end up becoming a `ConstArgKind::Path` instead, which
  has no `DefId`. We have to solve this in a hacky way where we guess
  whether the `AnonConst` could end up as a path const since we can't
  know for sure until after name resolution (`N` could refer to a free
  const or a nullary struct). If it has no chance as being a const
  param, then we create a `DefId` in `DefCollector` -- otherwise we
  decide during ast_lowering. This will have to be updated once all path
  consts use `ConstArgKind::Path`.

- We explicitly use `ConstArgHasType` for array lengths, rather than
  implicitly relying on anon const type feeding -- this is due to the
  addition of `ConstArgKind::Path`.

- Some tests have their outputs changed, but the changes are for the
  most part minor (including removing duplicate or almost-duplicate
  errors). One test now ICEs, but it is for an incomplete, unstable
  feature and is now tracked at #127009.
2024-07-16 19:27:28 -07:00
Trevor Gross
059222ddc9
Rollup merge of #127501 - compiler-errors:invert-infer-error-mod-struture, r=lcnr
Invert infer `error_reporting` mod struture

Parallel change to #127493, which moves `rustc_infer::infer::error_reporting` to `rustc_infer::error_reporting::infer`. After this, we should just be able to merge this into `rustc_trait_selection::error_reporting::infer`, and pull down `TypeErrCtxt` into that crate. 👍

r? lcnr
2024-07-16 16:15:16 -05:00
yukang
48ddf5e323 Fix the issue of invalid suggestion for a reference of iterator 2024-07-16 22:01:55 +08:00
Michael Goulet
e86fbcfd70 Move rustc_infer::infer::error_reporting to rustc_infer::error_reporting::infer 2024-07-15 20:16:12 -04:00
Michael Goulet
841b30f63e Make sure trait def ids match before zipping args in note_function_argument_obligation 2024-07-15 17:53:22 -04:00
Michael Goulet
172cf9bef3 Fix unsoundness when associated types dont actually come from supertraits 2024-07-15 14:17:32 -04:00
Michael Goulet
8edf9b8084 Item bounds can reference self projections and still be object safe 2024-07-15 14:16:48 -04:00
Jubilee
4bfc10617a
Rollup merge of #127631 - compiler-errors:yeet-fully-norm, r=lcnr
Remove `fully_normalize`

Yeet this function and replace it w/ some `ObligationCtxt` instead. It wasn't called very often anyways.

r? lcnr
2024-07-12 13:47:09 -07:00
Michael Goulet
2c8bbeebf1 Remove fully_normalize 2024-07-11 19:15:04 -04:00
Georg Semmler
27d5db166e
Allows #[diagnostic::do_not_recommend] to supress trait impls in suggestions as well
This commit changes the error reporting mechanism for not implemented
traits to skip impl marked as `#[diagnostic::do_not_recommend]` in the
help part of the error message ("the following other types implement
trait `Foo`:"). The main use case here is to allow crate authors to skip
non-meaningful confusing suggestions. A common example for this are
fully generic impls on tuples.
2024-07-11 08:14:28 +02:00
Matthias Krüger
22df186d6f
Rollup merge of #127570 - lcnr:normalize-cool, r=compiler-errors
small normalization improvement

r? `@compiler-errors`
2024-07-10 17:54:29 +02:00
lcnr
e00fd781c9 simplify and future-proof needs_normalization 2024-07-10 15:56:20 +02:00
lcnr
f77394fdf3 instantiate higher ranked goals in candidate selection
reverts #119820
2024-07-10 14:13:16 +02:00
Michael Goulet
bbbff80603 Split out fulfillment error reporting a bit more 2024-07-09 09:57:16 -04:00
Michael Goulet
cd68a28daa Move some stuff into the ambiguity and suggestion modules 2024-07-09 09:51:56 -04:00
Michael Goulet
7af825fea4 Split out overflow handling into its own module 2024-07-09 09:51:56 -04:00
Michael Goulet
fe4c995ccb Move trait selection error reporting to its own top-level module 2024-07-08 16:04:47 -04:00
许杰友 Jieyou Xu (Joe)
ffb93361b4
Rollup merge of #127439 - compiler-errors:uplift-elaborate, r=lcnr
Uplift elaboration into `rustc_type_ir`

Allows us to deduplicate and consolidate elaboration (including these stupid elaboration duplicate fns i added for pretty printing like 3 years ago) so I'm pretty hyped about this change :3

r? lcnr
2024-07-08 13:04:33 +08:00
许杰友 Jieyou Xu (Joe)
928d71f17b
Rollup merge of #127437 - compiler-errors:uplift-trait-ref-is-knowable, r=lcnr
Uplift trait ref is knowable into `rustc_next_trait_solver`

Self-explanatory. Eliminates one more delegate method.

r? lcnr cc ``@fmease``
2024-07-08 13:04:32 +08:00
bors
89aefb9c53 Auto merge of #127172 - compiler-errors:full-can_eq-everywhere, r=lcnr
Make `can_eq` process obligations (almost) everywhere

Move `can_eq` to an extension trait on `InferCtxt` in `rustc_trait_selection`, and change it so that it processes obligations. This should strengthen it to be more accurate in some cases, but is most important for the new trait solver which delays relating aliases to `AliasRelate` goals. Without this, we always basically just return true when passing aliases to `can_eq`, which can lead to weird errors, for example #127149.

I'm not actually certain if we should *have* `can_eq` be called on the good path. In cases where we need `can_eq`, we probably should just be using a regular probe.

Fixes #127149

r? lcnr
2024-07-07 23:03:48 +00:00
Michael Goulet
15d16f1cd6 Finish uplifting supertraits 2024-07-07 11:28:01 -04:00
Michael Goulet
ab27c2fa77 Get rid of trait_ref_is_knowable from delegate 2024-07-07 11:10:48 -04:00
Michael Goulet
a982471e07 Uplift trait_ref_is_knowable and friends 2024-07-07 11:10:32 -04:00
Michael Goulet
b2e30bdec4 Add fundamental to trait def 2024-07-07 11:10:32 -04:00
Michael Goulet
58aad3c72c iter_identity is a better name 2024-07-07 00:12:35 -04:00
bors
9e27377bec Auto merge of #127404 - compiler-errors:rpitit-entailment-false-positive, r=oli-obk
Don't try to label `ObligationCauseCode::CompareImplItem` for an RPITIT, since it has no name

The old (current) trait solver has a limitation that when a where clause in param-env must be normalized using the same where clause, then we get spurious errors in `normalize_param_env_or_error`. I don't think there's an issue tracking it, but it's the root cause for many of the "fixed-by-next-solver" labeled issues.

Specifically, these errors may occur when checking predicate entailment of the GAT that comes out of desugaring RPITITs. Since we use `ObligationCauseCode::CompareImplItem` for these predicates, we try calling `item_name` on an RPITIT which fails, since the RPITIT has no name.

We simply suppress this logic when we're reporting a predicate entailment error for an RPITIT. RPITITs should never have predicate entailment errors, *by construction*, but they may due to this bug in the old solver.

Addresses the ICE in #127331, though doesn't fix the underlying issue (which is fundamental to the old solver).

r? types
2024-07-07 03:22:12 +00:00
Michael Goulet
d6276b37ea Don't try to label ObligationCauseCode::CompareImplItem for an RPITIT, since it has no name 2024-07-06 15:20:37 -04:00
Michael Goulet
cc6c5de39d Import via rustc_type_ir::outlives
We could use rustc_middle::ty::outlives I guess?
2024-07-06 10:47:46 -04:00
Michael Goulet
23c6f23b21 Uplift push_outlives_components 2024-07-06 10:47:46 -04:00
Michael Goulet
a3535b963b
Rollup merge of #127366 - oli-obk:falliblevisitor, r=compiler-errors
Use `ControlFlow` results for visitors that are only looking for a single value

These visitors all had a `Option<Value>` or `bool` field, that, once set, was never unset or modified again. They have been refactored by removing the field and returning `ControlFlow` directly from the visitor
2024-07-05 20:49:34 -04:00
Michael Goulet
27588d1de3 Split SolverDelegate back out from InferCtxtLike 2024-07-05 16:39:39 -04:00
Michael Goulet
fb8d5f1e13 Actually just make can_eq process obligations (almost) everywhere 2024-07-05 11:59:54 -04:00
Oli Scherer
7dca61b68b Use ControlFlow results for visitors that are only looking for a single value 2024-07-05 15:00:40 +00:00
bors
c872a1418a Auto merge of #125507 - compiler-errors:type-length-limit, r=lcnr
Re-implement a type-size based limit

r? lcnr

This PR reintroduces the type length limit added in #37789, which was accidentally made practically useless by the caching changes to `Ty::walk` in #72412, which caused the `walk` function to no longer walk over identical elements.

Hitting this length limit is not fatal unless we are in codegen -- so it shouldn't affect passes like the mir inliner which creates potentially very large types (which we observed, for example, when the new trait solver compiles `itertools` in `--release` mode).

This also increases the type length limit from `1048576 == 2 ** 20` to `2 ** 24`, which covers all of the code that can be reached with craterbot-check. Individual crates can increase the length limit further if desired.

Perf regression is mild and I think we should accept it -- reinstating this limit is important for the new trait solver and to make sure we don't accidentally hit more type-size related regressions in the future.

Fixes #125460
2024-07-03 11:56:36 +00:00