diff options
6 files changed, 74 insertions, 4 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index ef3d300020a..f9f80f9d58c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2546,7 +2546,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()) }) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 186109e7075..bb6d7d0e8df 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -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 diff --git a/src/test/ui/traits/predicate_can_apply-hang.rs b/src/test/ui/traits/predicate_can_apply-hang.rs new file mode 100644 index 00000000000..5f01645da52 --- /dev/null +++ b/src/test/ui/traits/predicate_can_apply-hang.rs @@ -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() {} diff --git a/src/test/ui/traits/predicate_can_apply-hang.stderr b/src/test/ui/traits/predicate_can_apply-hang.stderr new file mode 100644 index 00000000000..49fe63b412a --- /dev/null +++ b/src/test/ui/traits/predicate_can_apply-hang.stderr @@ -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`. diff --git a/src/test/ui/typeck/hang-in-overflow.rs b/src/test/ui/typeck/hang-in-overflow.rs new file mode 100644 index 00000000000..a8330c9b65c --- /dev/null +++ b/src/test/ui/typeck/hang-in-overflow.rs @@ -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() {} diff --git a/src/test/ui/typeck/hang-in-overflow.stderr b/src/test/ui/typeck/hang-in-overflow.stderr new file mode 100644 index 00000000000..7a7b85b19b4 --- /dev/null +++ b/src/test/ui/typeck/hang-in-overflow.stderr @@ -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`. |
