Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hang in where-clause suggestion with predicate_can_apply #104269

Merged
merged 3 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2544,7 +2544,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let obligation =
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);

self.predicate_may_hold(&obligation)
// We don't use `InferCtxt::predicate_may_hold` because that
// will re-run predicates that overflow locally, which ends up
// taking a really long time to compute.
self.evaluate_obligation(&obligation).map_or(false, |eval| eval.may_apply())
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1340,9 +1340,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
obligation.param_env,
trait_pred_and_suggested_ty,
);
let suggested_ty_would_satisfy_obligation = self
.evaluate_obligation_no_overflow(&new_obligation)
.must_apply_modulo_regions();
let suggested_ty_would_satisfy_obligation =
self.predicate_must_hold_modulo_regions(&new_obligation);
if suggested_ty_would_satisfy_obligation {
let sp = self
.tcx
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/traits/predicate_can_apply-hang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn f<B>(x: Vec<[[[B; 1]; 1]; 1]>) -> impl PartialEq<B> {
//~^ ERROR can't compare `Vec<[[[B; 1]; 1]; 1]>` with `B`
x
}

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/traits/predicate_can_apply-hang.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0277]: can't compare `Vec<[[[B; 1]; 1]; 1]>` with `B`
--> $DIR/predicate_can_apply-hang.rs:1:38
|
LL | fn f<B>(x: Vec<[[[B; 1]; 1]; 1]>) -> impl PartialEq<B> {
| ^^^^^^^^^^^^^^^^^ no implementation for `Vec<[[[B; 1]; 1]; 1]> == B`
LL |
LL | x
| - return type was inferred to be `Vec<[[[B; 1]; 1]; 1]>` here
|
= help: the trait `PartialEq<B>` is not implemented for `Vec<[[[B; 1]; 1]; 1]>`
= help: the following other types implement trait `PartialEq<Rhs>`:
<Vec<T, A1> as PartialEq<Vec<U, A2>>>
<Vec<T, A> as PartialEq<&[U; N]>>
<Vec<T, A> as PartialEq<&[U]>>
<Vec<T, A> as PartialEq<&mut [U]>>
<Vec<T, A> as PartialEq<[U; N]>>
<Vec<T, A> as PartialEq<[U]>>

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
19 changes: 19 additions & 0 deletions src/test/ui/typeck/hang-in-overflow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// normalize-stderr-test "the requirement `.*`" -> "the requirement `...`"
// normalize-stderr-test "required for `.*` to implement `.*`" -> "required for `...` to implement `...`"
// normalize-stderr-test: ".*the full type name has been written to.*\n" -> ""

// Currently this fatally aborts instead of hanging.
// Make sure at least that this doesn't turn into a hang.

fn f() {
foo::<_>();
//~^ ERROR overflow evaluating the requirement
}

fn foo<B>()
where
Vec<[[[B; 1]; 1]; 1]>: PartialEq<B>,
{
}

fn main() {}
22 changes: 22 additions & 0 deletions src/test/ui/typeck/hang-in-overflow.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0275]: overflow evaluating the requirement `...`
--> $DIR/hang-in-overflow.rs:9:5
|
LL | foo::<_>();
| ^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hang_in_overflow`)
= note: required for `...` to implement `...`
= note: 127 redundant requirements hidden
= note: required for `...` to implement `...`
note: required by a bound in `foo`
--> $DIR/hang-in-overflow.rs:15:28
|
LL | fn foo<B>()
| --- required by a bound in this
LL | where
LL | Vec<[[[B; 1]; 1]; 1]>: PartialEq<B>,
| ^^^^^^^^^^^^ required by this bound in `foo`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.