Skip to content

Commit

Permalink
Auto merge of rust-lang#127404 - compiler-errors:rpitit-entailment-fa…
Browse files Browse the repository at this point in the history
…lse-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 rust-lang#127331, though doesn't fix the underlying issue (which is fundamental to the old solver).

r? types
  • Loading branch information
bors committed Jul 7, 2024
2 parents 289deb9 + d6276b3 commit 9e27377
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3472,6 +3472,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
)
});
}
// Suppress `compare_type_predicate_entailment` errors for RPITITs, since they
// should be implied by the parent method.
ObligationCauseCode::CompareImplItem { trait_item_def_id, .. }
if tcx.is_impl_trait_in_trait(trait_item_def_id) => {}
ObligationCauseCode::CompareImplItem { trait_item_def_id, kind, .. } => {
let item_name = tcx.item_name(trait_item_def_id);
let msg = format!(
Expand Down
24 changes: 0 additions & 24 deletions tests/crashes/125099.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:36:5
|
LL | / fn autobatch<F>(self) -> impl Trait
LL | |
LL | |
LL | |
... |
LL | | where
LL | | F: Callback<Self::CallbackArg>,
| |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:36:30
|
LL | fn autobatch<F>(self) -> impl Trait
| ^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `<Sender as ChannelSender>::autobatch`
--> $DIR/false-positive-predicate-entailment-error.rs:43:12
|
LL | fn autobatch<F>(self) -> impl Trait
| --------- required by a bound in this associated function
...
LL | F: Callback<Self::CallbackArg>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<Sender as ChannelSender>::autobatch`
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:36:5
|
LL | / fn autobatch<F>(self) -> impl Trait
LL | |
LL | |
LL | |
... |
LL | | where
LL | | F: Callback<Self::CallbackArg>,
| |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error[E0277]: the trait bound `F: Callback<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:43:12
|
LL | F: Callback<Self::CallbackArg>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: the requirement `F: Callback<i32>` appears on the `impl`'s method `autobatch` but not on the corresponding trait's method
--> $DIR/false-positive-predicate-entailment-error.rs:25:8
|
LL | trait ChannelSender {
| ------------- in this trait
...
LL | fn autobatch<F>(self) -> impl Trait
| ^^^^^^^^^ this trait's method doesn't have the requirement `F: Callback<i32>`
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:36:30
|
LL | fn autobatch<F>(self) -> impl Trait
| ^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here

error[E0277]: the trait bound `F: Callback<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:27:12
|
LL | F: Callback<Self::CallbackArg>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here

error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:36:5
|
LL | / fn autobatch<F>(self) -> impl Trait
LL | |
LL | |
LL | |
... |
LL | | where
LL | | F: Callback<Self::CallbackArg>,
| |_______________________________________^ the trait `MyFn<i32>` is not implemented for `F`, which is required by `F: Callback<i32>`
|
note: required for `F` to implement `Callback<i32>`
--> $DIR/false-positive-predicate-entailment-error.rs:14:21
|
LL | impl<A, F: MyFn<A>> Callback<A> for F {
| ------- ^^^^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error[E0277]: the trait bound `F: MyFn<i32>` is not satisfied
--> $DIR/false-positive-predicate-entailment-error.rs:43:12
|
LL | F: Callback<Self::CallbackArg>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyFn<i32>` is not implemented for `F`
|
note: required by a bound in `Callback`
--> $DIR/false-positive-predicate-entailment-error.rs:10:20
|
LL | trait Callback<A>: MyFn<A, Output = Self::Ret> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Callback`
help: consider further restricting this bound
|
LL | F: Callback<Self::CallbackArg> + MyFn<i32>,
| +++++++++++

error: aborting due to 8 previous errors

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@[next] check-pass

trait MyFn<T> {
type Output;
}

trait Callback<A>: MyFn<A, Output = Self::Ret> {
type Ret;
}

impl<A, F: MyFn<A>> Callback<A> for F {
type Ret = F::Output;
}

struct Thing;
trait Trait {}
impl Trait for Thing {}

trait ChannelSender {
type CallbackArg;

fn autobatch<F>(self) -> impl Trait
where
F: Callback<Self::CallbackArg>;
//[current]~^ ERROR the trait bound `F: Callback<i32>` is not satisfied
}

struct Sender;

impl ChannelSender for Sender {
type CallbackArg = i32;

fn autobatch<F>(self) -> impl Trait
//[current]~^ ERROR the trait bound `F: MyFn<i32>` is not satisfied
//[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied
//[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied
//[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied
//[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied
where
F: Callback<Self::CallbackArg>,
//[current]~^ ERROR the trait bound `F: Callback<i32>` is not satisfied
//[current]~| ERROR the trait bound `F: MyFn<i32>` is not satisfied
{
Thing
}
}

fn main() {}

0 comments on commit 9e27377

Please sign in to comment.