Rollup merge of #117133 - compiler-errors:coherence-constrained, r=oli-obk

Merge `impl_wf_inference` (`check_mod_impl_wf`) check into coherence checking

Problem here is that we call `collect_impl_trait_in_trait_types` when checking `check_mod_impl_wf` which is performed before coherence. Due to the `tcx.sess.track_errors`, since we end up reporting an error, we never actually proceed to coherence checking, where we would be emitting a more useful impl overlap error.

This change means that we may report more errors in some cases, but can at least proceed far enough to leave a useful message for overlapping traits with RPITITs in them.

Fixes #116982

r? types
This commit is contained in:
Matthias Krüger 2023-10-25 17:40:29 +02:00 committed by GitHub
commit 96074bec97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 15 deletions

View File

@ -181,14 +181,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
})?;
}
tcx.sess.track_errors(|| {
tcx.sess.time("impl_wf_inference", || {
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module))
});
})?;
tcx.sess.track_errors(|| {
tcx.sess.time("coherence_checking", || {
// Check impls constrain their parameters
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
tcx.ensure().coherent_trait(trait_def_id);
}

View File

@ -0,0 +1,26 @@
// edition: 2021
trait Foo {
type T;
async fn foo(&self) -> Self::T;
}
struct Bar;
impl Foo for Bar {
type T = ();
async fn foo(&self) {}
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
}
impl Foo for Bar {
//~^ ERROR conflicting implementations of trait `Foo` for type `Bar`
type T = ();
async fn foo(&self) {}
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
}
fn main() {}

View File

@ -0,0 +1,25 @@
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
--> $DIR/coherence-constrained.rs:14:5
|
LL | async fn foo(&self) {}
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
--> $DIR/coherence-constrained.rs:22:5
|
LL | async fn foo(&self) {}
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
error[E0119]: conflicting implementations of trait `Foo` for type `Bar`
--> $DIR/coherence-constrained.rs:18:1
|
LL | impl Foo for Bar {
| ---------------- first implementation here
...
LL | impl Foo for Bar {
| ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0119, E0284.
For more information about an error, try `rustc --explain E0119`.

View File

@ -1,3 +1,5 @@
//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized
trait Foo<A> {
fn get(&self, A: &A) { }
}
@ -23,8 +25,7 @@ impl<T:Bar<Out=U>,U> Foo<T> for [isize;3] {
}
impl<T,U> Foo<T> for U {
// OK, T, U are used everywhere. Note that the coherence check
// hasn't executed yet, so no errors about overlap.
//~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
}
impl<T,U> Bar for T {

View File

@ -1,33 +1,56 @@
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
--> $DIR/impl-unused-tps.rs:13:8
--> $DIR/impl-unused-tps.rs:15:8
|
LL | impl<T,U> Foo<T> for [isize;1] {
| ^ unconstrained type parameter
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
--> $DIR/impl-unused-tps.rs:30:8
--> $DIR/impl-unused-tps.rs:31:8
|
LL | impl<T,U> Bar for T {
| ^ unconstrained type parameter
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
--> $DIR/impl-unused-tps.rs:38:8
--> $DIR/impl-unused-tps.rs:39:8
|
LL | impl<T,U> Bar for T
| ^ unconstrained type parameter
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
--> $DIR/impl-unused-tps.rs:46:8
--> $DIR/impl-unused-tps.rs:47:8
|
LL | impl<T,U,V> Foo<T> for T
| ^ unconstrained type parameter
error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
--> $DIR/impl-unused-tps.rs:46:10
--> $DIR/impl-unused-tps.rs:47:10
|
LL | impl<T,U,V> Foo<T> for T
| ^ unconstrained type parameter
error: aborting due to 5 previous errors
error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
--> $DIR/impl-unused-tps.rs:27:1
|
LL | impl<T> Foo<T> for [isize;0] {
| ---------------------------- first implementation here
...
LL | impl<T,U> Foo<T> for U {
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
For more information about this error, try `rustc --explain E0207`.
error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`)
note: required for `([isize; 0], _)` to implement `Bar`
--> $DIR/impl-unused-tps.rs:31:11
|
LL | impl<T,U> Bar for T {
| - ^^^ ^
| |
| unsatisfied trait bound introduced here
= note: 126 redundant requirements hidden
= note: required for `([isize; 0], _)` to implement `Bar`
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0119, E0207, E0275.
For more information about an error, try `rustc --explain E0119`.