Skip to content

Commit 77de5f0

Browse files
authored
Rollup merge of #110618 - compiler-errors:eval-ctxt-tainted, r=BoxyUwU
Track if EvalCtxt has been tainted, make sure it can't be used to make query responses after Just some additional protection against missing probes or strange candidate assembly behavior in the new solver. For background, we don't ever want to call `evaluate_added_goals_and_make_canonical_response` if a previous call to `try_evaluate_added_goals` has bailed with `NoSolution`, since our nested goals are left in an undefined state at that point. This most commonly suggests a missing `EvalCtxt::probe`, but could also signify some other shenanigans like dropping a `QueryResult` on the floor without properly `?`'ing it. r? `@lcnr`
2 parents ea01135 + 3206100 commit 77de5f0

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

+15
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> {
5757
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
5858

5959
pub(super) nested_goals: NestedGoals<'tcx>,
60+
61+
// Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
62+
//
63+
// If so, then it can no longer be used to make a canonical query response,
64+
// since subsequent calls to `try_evaluate_added_goals` have possibly dropped
65+
// ambiguous goals. Instead, a probe needs to be introduced somewhere in the
66+
// evaluation code.
67+
tainted: Result<(), NoSolution>,
6068
}
6169

6270
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
121129
max_input_universe: ty::UniverseIndex::ROOT,
122130
var_values: CanonicalVarValues::dummy(),
123131
nested_goals: NestedGoals::new(),
132+
tainted: Ok(()),
124133
};
125134
let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
126135

@@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
172181
max_input_universe: canonical_goal.max_universe,
173182
search_graph,
174183
nested_goals: NestedGoals::new(),
184+
tainted: Ok(()),
175185
};
176186
ecx.compute_goal(goal)
177187
})
@@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
391401
},
392402
);
393403

404+
if response.is_err() {
405+
self.tainted = Err(NoSolution);
406+
}
407+
394408
self.nested_goals = goals;
395409
response
396410
}
@@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
404418
max_input_universe: self.max_input_universe,
405419
search_graph: self.search_graph,
406420
nested_goals: self.nested_goals.clone(),
421+
tainted: self.tainted,
407422
};
408423
self.infcx.probe(|_| f(&mut ecx))
409424
}

compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

+7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
5151
certainty: Certainty,
5252
) -> QueryResult<'tcx> {
5353
let goals_certainty = self.try_evaluate_added_goals()?;
54+
assert_eq!(
55+
self.tainted,
56+
Ok(()),
57+
"EvalCtxt is tainted -- nested goals may have been dropped in a \
58+
previous call to `try_evaluate_added_goals!`"
59+
);
60+
5461
let certainty = certainty.unify_with(goals_certainty);
5562

5663
let external_constraints = self.compute_external_query_constraints()?;

0 commit comments

Comments
 (0)