Skip to content
/ rust Public
forked from rust-lang/rust

Commit 7e47aea

Browse files
authored
Rollup merge of rust-lang#159964 - amirHdev:fix-placeholder-certainty, r=lcnr
Preserve placeholder ambiguity during normalization Fixes rust-lang#159896
2 parents 2b3a462 + ba4e2f6 commit 7e47aea

2 files changed

Lines changed: 37 additions & 10 deletions

File tree

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,19 +1526,16 @@ where
15261526
) -> QueryResultOrRerunNonErased<I> {
15271527
self.inspect.make_canonical_response(shallow_certainty);
15281528

1529-
let goals_certainty = self.try_evaluate_added_goals()?;
1529+
let added_goals_certainty = self.try_evaluate_added_goals()?;
15301530
assert_eq!(
15311531
self.tainted,
15321532
Ok(()),
15331533
"EvalCtxt is tainted -- nested goals may have been dropped in a \
15341534
previous call to `try_evaluate_added_goals!`"
15351535
);
15361536

1537-
let goals_certainty = match self.delegate.cx().assumptions_on_binders() {
1538-
true => {
1539-
let certainty = self.eagerly_handle_placeholders()?;
1540-
certainty.and(goals_certainty)
1541-
}
1537+
let placeholder_certainty = match self.delegate.cx().assumptions_on_binders() {
1538+
true => self.eagerly_handle_placeholders()?,
15421539
false => {
15431540
// We only check for leaks from universes which were entered inside
15441541
// of the query.
@@ -1547,9 +1544,10 @@ where
15471544
NoSolution
15481545
})?;
15491546

1550-
goals_certainty
1547+
Certainty::Yes
15511548
}
15521549
};
1550+
let goals_certainty = placeholder_certainty.and(added_goals_certainty);
15531551

15541552
let (certainty, normalization_nested_goals) =
15551553
match (self.current_goal_kind, shallow_certainty) {
@@ -1563,12 +1561,13 @@ where
15631561
(CurrentGoalKind::ProjectionComputeAssocTermCandidate, Certainty::Yes) => {
15641562
let goals = std::mem::take(&mut self.nested_goals);
15651563
// As we return all ambiguous nested goals, we can ignore the certainty
1566-
// returned by `self.try_evaluate_added_goals()`.
1564+
// returned by `self.try_evaluate_added_goals()`. However, placeholder
1565+
// handling may independently be ambiguous, so preserve its certainty.
15671566
if goals.is_empty() {
1568-
assert!(matches!(goals_certainty, Certainty::Yes));
1567+
assert!(matches!(added_goals_certainty, Certainty::Yes));
15691568
}
15701569
(
1571-
Certainty::Yes,
1570+
placeholder_certainty,
15721571
NestedNormalizationGoals(
15731572
goals.into_iter().map(|(s, g, _)| (s, g)).collect(),
15741573
),
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Regression test for issue #159896.
2+
//
3+
// An ambiguous result from eagerly handling placeholders must be preserved
4+
// when returning nested normalization goals, instead of causing an ICE.
5+
6+
//@ check-fail
7+
//@ dont-check-compiler-stderr
8+
//@ dont-require-annotations: ERROR
9+
//@ compile-flags: -Znext-solver=globally -Zassumptions-on-binders
10+
//@ edition: 2021
11+
12+
#![feature(type_alias_impl_trait)]
13+
14+
type FooArg<'a> = &'a impl Iterator<Item = FooItem>;
15+
type FooRet = impl Iterator<Item = FooItem>;
16+
type FooItem = Box<dyn Fn(FooArg) -> FooRet>;
17+
18+
struct Bar;
19+
20+
impl Iterator for Bar {
21+
type Item = FooItem;
22+
23+
fn next(&mut self) -> Option<Self::Item> {
24+
todo!()
25+
}
26+
}
27+
28+
fn main() {}

0 commit comments

Comments
 (0)