- Ok((
- !canonical_response.value.var_values.is_identity(),
- instantiate_canonical_query_response(self.infcx, &orig_values, canonical_response),
- ))
+
+ let has_changed = !canonical_response.value.var_values.is_identity();
+ let certainty =
+ instantiate_canonical_query_response(self.infcx, &orig_values, canonical_response);
+
+ // Check that rerunning this query with its inference constraints applied
+ // doesn't result in new inference constraints and has the same result.
+ //
+ // If we have projection goals like `<T as Trait>::Assoc == u32` we recursively
+ // call `exists<U> <T as Trait>::Assoc == U` to enable better caching. This goal
+ // could constrain `U` to `u32` which would cause this check to result in a
+ // solver cycle.
+ if cfg!(debug_assertions) && has_changed && !self.in_projection_eq_hack {
+ let mut orig_values = OriginalQueryValues::default();
+ let canonical_goal = self.infcx.canonicalize_query(goal, &mut orig_values);
+ let canonical_response =
+ EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
+ assert!(canonical_response.value.var_values.is_identity());
+ assert_eq!(certainty, canonical_response.value.certainty);
+ }
+
+ Ok((has_changed, certainty))