diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 900d55cc556fc..7f66f08b0caa1 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -24,6 +24,7 @@ use super::{ PredicateObligation, ProjectionCacheEntry, ProjectionCacheKey, Selection, SelectionContext, SelectionError, specialization_graph, translate_args, util, }; +use crate::error_reporting::InferCtxtErrorExt; use crate::errors::InherentProjectionNormalizationOverflow; use crate::infer::{BoundRegionConversionTime, InferOk}; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; @@ -233,6 +234,7 @@ fn project_and_unify_term<'cx, 'tcx>( obligation.cause.span, obligation.param_env, ); + debug!(?new, "replace_opaque_types_with_inference_vars new obligations"); obligations.extend(new); // Need to define opaque types to support nested opaque types like `impl Fn() -> impl Trait` @@ -242,6 +244,15 @@ fn project_and_unify_term<'cx, 'tcx>( actual, ) { Ok(InferOk { obligations: inferred_obligations, value: () }) => { + // If we are adding any new obligations, make sure we are not recursing infinitely + // Since the general recursion check in `process_obligation` is explicitly skipped for us + if !inferred_obligations.is_empty() { + if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) { + selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false); + } + } + + debug!(?inferred_obligations, "obligations from eq"); obligations.extend(inferred_obligations); ProjectAndUnifyResult::Holds(obligations) } diff --git a/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.next.stderr b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.next.stderr new file mode 100644 index 0000000000000..e6879d4a4d16d --- /dev/null +++ b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.next.stderr @@ -0,0 +1,26 @@ +error[E0283]: type annotations needed + --> $DIR/non-termination-while-reporting-ambiguity-error-issue-1156615.rs:28:10 + | +LL | .cartesian_product(Family::Distribution::single_value()) + | ^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the method `cartesian_product` +LL | +LL | .flatten::() + | ------- type must be known at this point + | + = note: the type must implement `Distribution` +note: required by a bound in `Distribution::flatten` + --> $DIR/non-termination-while-reporting-ambiguity-error-issue-1156615.rs:22:16 + | +LL | fn flatten(self) -> ::Distribution + | ------- required by a bound in this associated function +LL | where +LL | Value: Distribution; + | ^^^^^^^^^^^^^^^ required by this bound in `Distribution::flatten` +help: consider specifying the generic arguments + | +LL | .cartesian_product::(Family::Distribution::single_value()) + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.old.stderr b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.old.stderr new file mode 100644 index 0000000000000..27d80dafd3c08 --- /dev/null +++ b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.old.stderr @@ -0,0 +1,5 @@ +error[E0275]: overflow evaluating the requirement `::Distribution<_> == _` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.rs b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.rs new file mode 100644 index 0000000000000..636e3787fd311 --- /dev/null +++ b/tests/ui/typeck/non-termination-while-reporting-ambiguity-error-issue-1156615.rs @@ -0,0 +1,33 @@ +//[old]~ ERROR overflow evaluating the requirement `::Distribution<_> == _` [E0275] +//@ revisions: old next +//@[next] compile-flags: -Znext-solver + + +pub trait DistributionFamily { + type Distribution: Distribution; +} + +pub trait Distribution { + type Family: DistributionFamily; + + fn single_value() -> Self; + + fn cartesian_product( + self, + other: ::Distribution, + ) -> ::Distribution; + + fn flatten(self) -> ::Distribution + where + Value: Distribution; +} + + +fn start_event() -> Family::Distribution { + Family::Distribution::single_value() + .cartesian_product(Family::Distribution::single_value()) + //[next]~^ ERROR type annotations needed + .flatten::() +} + +fn main() {}