diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 156dfc4fc1e69..0ca31272fdfec 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1526,7 +1526,7 @@ where ) -> QueryResultOrRerunNonErased { self.inspect.make_canonical_response(shallow_certainty); - let goals_certainty = self.try_evaluate_added_goals()?; + let added_goals_certainty = self.try_evaluate_added_goals()?; assert_eq!( self.tainted, Ok(()), @@ -1534,11 +1534,8 @@ where previous call to `try_evaluate_added_goals!`" ); - let goals_certainty = match self.delegate.cx().assumptions_on_binders() { - true => { - let certainty = self.eagerly_handle_placeholders()?; - certainty.and(goals_certainty) - } + let placeholder_certainty = match self.delegate.cx().assumptions_on_binders() { + true => self.eagerly_handle_placeholders()?, false => { // We only check for leaks from universes which were entered inside // of the query. @@ -1547,9 +1544,10 @@ where NoSolution })?; - goals_certainty + Certainty::Yes } }; + let goals_certainty = placeholder_certainty.and(added_goals_certainty); let (certainty, normalization_nested_goals) = match (self.current_goal_kind, shallow_certainty) { @@ -1563,12 +1561,13 @@ where (CurrentGoalKind::ProjectionComputeAssocTermCandidate, Certainty::Yes) => { let goals = std::mem::take(&mut self.nested_goals); // As we return all ambiguous nested goals, we can ignore the certainty - // returned by `self.try_evaluate_added_goals()`. + // returned by `self.try_evaluate_added_goals()`. However, placeholder + // handling may independently be ambiguous, so preserve its certainty. if goals.is_empty() { - assert!(matches!(goals_certainty, Certainty::Yes)); + assert!(matches!(added_goals_certainty, Certainty::Yes)); } ( - Certainty::Yes, + placeholder_certainty, NestedNormalizationGoals( goals.into_iter().map(|(s, g, _)| (s, g)).collect(), ), diff --git a/tests/ui/assumptions_on_binders/ambiguous-placeholder-certainty-issue-159896.rs b/tests/ui/assumptions_on_binders/ambiguous-placeholder-certainty-issue-159896.rs new file mode 100644 index 0000000000000..afe7b1808a96b --- /dev/null +++ b/tests/ui/assumptions_on_binders/ambiguous-placeholder-certainty-issue-159896.rs @@ -0,0 +1,28 @@ +// Regression test for issue #159896. +// +// An ambiguous result from eagerly handling placeholders must be preserved +// when returning nested normalization goals, instead of causing an ICE. + +//@ check-fail +//@ dont-check-compiler-stderr +//@ dont-require-annotations: ERROR +//@ compile-flags: -Znext-solver=globally -Zassumptions-on-binders +//@ edition: 2021 + +#![feature(type_alias_impl_trait)] + +type FooArg<'a> = &'a impl Iterator; +type FooRet = impl Iterator; +type FooItem = Box FooRet>; + +struct Bar; + +impl Iterator for Bar { + type Item = FooItem; + + fn next(&mut self) -> Option { + todo!() + } +} + +fn main() {}