Provide more context on recursive `impl` evaluation overflow
When an associated type `Self::Assoc` is part of a `where` clause, we end up unable to evaluate the requirement and emit a E0275.
We now point at the associated type if specified in the `impl`. If so, we also suggest using that type instead of `Self::Assoc`. Otherwise, we explain that these are not allowed.
```
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-1.rs:15:1
|
LL | / impl<T: Grault> Grault for (T,)
LL | |
LL | | where
LL | | Self::A: Baz,
LL | | Self::B: Fiz,
| |_________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
...
LL | Self::A: Baz,
| --- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `(T,)` to implement `Grault`
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - Self::A: Baz,
|
```
```
error[E0275]: overflow evaluating the requirement `<T as B>::Type == <T as B>::Type`
--> $DIR/impl-wf-cycle-3.rs:7:1
|
LL | / impl<T> B for T
LL | | where
LL | | T: A<Self::Type>,
| |_____________________^
LL | {
LL | type Type = bool;
| --------- associated type `<T as B>::Type` is specified here
|
note: required for `T` to implement `B`
--> $DIR/impl-wf-cycle-3.rs:7:9
|
LL | impl<T> B for T
| ^ ^
LL | where
LL | T: A<Self::Type>,
| ------------- unsatisfied trait bound introduced here
help: replace the associated type with the type specified in this `impl`
|
LL | T: A<bool>,
| ~~~~
```
```
error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
--> $DIR/impl-wf-cycle-4.rs:5:1
|
LL | / impl<T> Filter for T
LL | | where
LL | | T: Fn(Self::ToMatch),
| |_________________________^
|
note: required for `T` to implement `Filter`
--> $DIR/impl-wf-cycle-4.rs:5:9
|
LL | impl<T> Filter for T
| ^^^^^^ ^
LL | where
LL | T: Fn(Self::ToMatch),
| ----------------- unsatisfied trait bound introduced here
note: associated types for the current `impl` cannot be restricted in `where` clauses
--> $DIR/impl-wf-cycle-4.rs:7:11
|
LL | T: Fn(Self::ToMatch),
| ^^^^^^^^^^^^^
```
Fix#116925
A bunch of random modifications
r? oli-obk
Kitchen sink of changes that I didn't know where to put elsewhere. Documentation tweaks mostly, but also removing some unreachable code and simplifying the pretty printing for closures/coroutines.
Expose Obligations created during type inference.
This PR is a first pass at exposing the trait obligations generated and solved for during the type-check progress. Exposing these obligations allows for rustc plugins to use the public interface for proof trees (provided by the next gen trait solver).
The changes proposed track *all* obligations during the type-check process, this is desirable to not only look at the trees of failed obligations, but also those of successfully proved obligations. This feature is placed behind an unstable compiler option `track-trait-obligations` which should be used together with the `next-solver` option. I should note that the main interface is the function `inspect_typeck` made public in `rustc_hir_typeck/src/lib.rs` which allows the caller to provide a callback granting access to the `FnCtxt`.
r? `@lcnr`
When an associated type `Self::Assoc` is part of a `where` clause,
we end up unable to evaluate the requirement and emit a E0275.
We now point at the associated type if specified in the `impl`. If
so, we also suggest using that type instead of `Self::Assoc`.
Otherwise, we explain that these are not allowed.
```
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-1.rs:15:1
|
LL | / impl<T: Grault> Grault for (T,)
LL | |
LL | | where
LL | | Self::A: Baz,
LL | | Self::B: Fiz,
| |_________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-1.rs:15:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
...
LL | Self::A: Baz,
| --- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `(T,)` to implement `Grault`
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - Self::A: Baz,
LL + ,
|
```
```
error[E0275]: overflow evaluating the requirement `<T as B>::Type == <T as B>::Type`
--> $DIR/impl-wf-cycle-3.rs:7:1
|
LL | / impl<T> B for T
LL | | where
LL | | T: A<Self::Type>,
| |_____________________^
LL | {
LL | type Type = bool;
| --------- associated type `<T as B>::Type` is specified here
|
note: required for `T` to implement `B`
--> $DIR/impl-wf-cycle-3.rs:7:9
|
LL | impl<T> B for T
| ^ ^
LL | where
LL | T: A<Self::Type>,
| ------------- unsatisfied trait bound introduced here
help: replace the associated type with the type specified in this `impl`
|
LL | T: A<bool>,
| ~~~~
```
```
error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
--> $DIR/impl-wf-cycle-4.rs:5:1
|
LL | / impl<T> Filter for T
LL | | where
LL | | T: Fn(Self::ToMatch),
| |_________________________^
|
note: required for `T` to implement `Filter`
--> $DIR/impl-wf-cycle-4.rs:5:9
|
LL | impl<T> Filter for T
| ^^^^^^ ^
LL | where
LL | T: Fn(Self::ToMatch),
| ----------------- unsatisfied trait bound introduced here
note: associated types for the current `impl` cannot be restricted in `where` clauses
--> $DIR/impl-wf-cycle-4.rs:7:11
|
LL | T: Fn(Self::ToMatch),
| ^^^^^^^^^^^^^
```
Fix#116925
Pass each obligation to an fn callback with its respective inference context. This avoids needing to keep around copies of obligations or inference contexts.
Specify usability of inspect_typeck in comment.
fix fn/const items implied bounds and wf check (rebase)
A rebase of #104098, see that PR for discussion. This is pretty much entirely the work of `@aliemjay.` I received his permission for this rebase.
---
These are two distinct changes (edit: actually three, see below):
1. Wf-check all fn item args. This is a soundness fix.
Fixes#104005
2. Use implied bounds from impl header in borrowck of associated functions/consts. This strictly accepts more code and helps to mitigate the impact of other breaking changes.
Fixes#98852Fixes#102611
The first is a breaking change and will likely have a big impact without the the second one. See the first commit for how it breaks libstd.
Landing the second one without the first will allow more incorrect code to pass. For example an exploit of #104005 would be as simple as:
```rust
use core::fmt::Display;
trait ExtendLt<Witness> {
fn extend(self) -> Box<dyn Display>;
}
impl<T: Display> ExtendLt<&'static T> for T {
fn extend(self) -> Box<dyn Display> {
Box::new(self)
}
}
fn main() {
let val = (&String::new()).extend();
println!("{val}");
}
```
The third change is to to check WF of user type annotations before normalizing them (fixes#104764, fixes#104763). It is mutually dependent on the second change above: an attempt to land it separately in #104746 caused several crater regressions that can all be mitigated by using the implied from the impl header. It is also necessary for the soundness of associated consts that use the implied bounds of impl header. See #104763 and how the third commit fixes the soundness issue in `tests/ui/wf/wf-associated-const.rs` that was introduces by the previous commit.
r? types
Fix `allow_internal_unstable` for `(min_)specialization`
Fixes#119950
Blocked on #119949 (comment doesn't make sense until that merges)
I'd like to follow this up and look for more instances of not properly checking spans for features but I wanted to fix the motivating issue.
`OutputTypeParameterMismatch` -> `SignatureMismatch`
I'm probably missing something that made this rename more complicated. What did you end up getting stuck on when renaming this selection error, `@lcnr?`
**also** I renamed the `FulfillmentErrorCode` variants. This is just churn but I wanted to do it forever. I can move it out of this PR if desired.
r? lcnr
Make `InferCtxtExt::could_impl_trait` more precise, less ICEy
The implementation for `InferCtxtExt::could_impl_trait` was very wrong. Along with being pretty poorly named, way too specific to ADTs, it was also doing impl substitution wrong -- this caused an ICE (#119915).
This PR generalizes that code, gives it a clearer name, makes it stop using the new trait solver (lol), and fixes some fallout bad suggestions that are made worse with the code fix.
Fixes#119915
Suggest Upgrading Compiler for Gated Features
This PR addresses #117318
I have a few questions:
1. Do we want to specify the current version and release date of the compiler? I have added this in via environment variables, which I found in the code for the rustc cli where it handles the `--version` flag
a. How can I handle the changing message in the tests?
3. Do we want to only show this message when the compiler is old?
a. How can we determine when the compiler is old?
I'll wait until we figure out the message to bless the tests
Remove special-casing around `AliasKind::Opaque` when structurally resolving in new solver
This fixes a few inconsistencies around where we don't eagerly resolve opaques to their (locally-defined) hidden types in the new solver. It essentially allows this code to work:
```rust
fn main() {
type Tait = impl Sized;
struct S {
i: i32,
}
let x: Tait = S { i: 0 };
println!("{}", x.i);
}
```
Since `Tait` is defined in `main`, we are able to poke through the type of `x` with deref.
r? lcnr
next solver: provisional cache
this adds the cache removed in #115843. However, it should now correctly track whether a provisional result depends on an inductive or coinductive stack.
While working on this, I was using the following doc: https://hackmd.io/VsQPjW3wSTGUSlmgwrDKOA. I don't think it's too helpful to understanding this, but am somewhat hopeful that the inline comments are more useful.
There are quite a few future perf improvements here. Given that this is already very involved I don't believe it is worth it (for now). While working on this PR one of my few attempts to significantly improve perf ended up being unsound again because I was not careful enough ✨
r? `@compiler-errors`
Diagnostic API fixes
Some improvements to diagnostic APIs: improve some naming, use shortcuts in more places, and add a couple of missing methods.
r? `@compiler-errors`