allow caller to force proof tree generation
This commit is contained in:
parent
51090b962f
commit
bb743f8635
2 changed files with 89 additions and 72 deletions
|
@ -9,7 +9,7 @@ use rustc_infer::infer::{
|
|||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_middle::traits::solve::inspect::CandidateKind;
|
||||
use rustc_middle::traits::solve::inspect::{self, CandidateKind};
|
||||
use rustc_middle::traits::solve::{
|
||||
CanonicalInput, CanonicalResponse, Certainty, MaybeCause, PredefinedOpaques,
|
||||
PredefinedOpaquesData, QueryResult,
|
||||
|
@ -108,6 +108,12 @@ impl NestedGoals<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
|
||||
pub enum GenerateProofTree {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
pub trait InferCtxtEvalExt<'tcx> {
|
||||
/// Evaluates a goal from **outside** of the trait solver.
|
||||
///
|
||||
|
@ -116,7 +122,11 @@ pub trait InferCtxtEvalExt<'tcx> {
|
|||
fn evaluate_root_goal(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
) -> Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>;
|
||||
generate_proof_tree: GenerateProofTree,
|
||||
) -> (
|
||||
Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
|
||||
Option<inspect::GoalEvaluation<'tcx>>,
|
||||
);
|
||||
}
|
||||
|
||||
impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
||||
|
@ -124,7 +134,11 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
|||
fn evaluate_root_goal(
|
||||
&self,
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
) -> Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
|
||||
generate_proof_tree: GenerateProofTree,
|
||||
) -> (
|
||||
Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
|
||||
Option<inspect::GoalEvaluation<'tcx>>,
|
||||
) {
|
||||
let mode = if self.intercrate { SolverMode::Coherence } else { SolverMode::Normal };
|
||||
let mut search_graph = search_graph::SearchGraph::new(self.tcx, mode);
|
||||
|
||||
|
@ -141,19 +155,16 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
|||
var_values: CanonicalVarValues::dummy(),
|
||||
nested_goals: NestedGoals::new(),
|
||||
tainted: Ok(()),
|
||||
inspect: self
|
||||
.tcx
|
||||
.sess
|
||||
.opts
|
||||
.unstable_opts
|
||||
.dump_solver_proof_tree
|
||||
inspect: (self.tcx.sess.opts.unstable_opts.dump_solver_proof_tree
|
||||
|| matches!(generate_proof_tree, GenerateProofTree::Yes))
|
||||
.then(ProofTreeBuilder::new_root)
|
||||
.unwrap_or_else(ProofTreeBuilder::new_noop),
|
||||
};
|
||||
let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
|
||||
|
||||
if let Some(tree) = ecx.inspect.finalize() {
|
||||
println!("{:?}", tree);
|
||||
let tree = ecx.inspect.finalize();
|
||||
if let Some(tree) = &tree {
|
||||
debug!(?tree);
|
||||
}
|
||||
|
||||
assert!(
|
||||
|
@ -162,7 +173,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
|||
);
|
||||
|
||||
assert!(search_graph.is_empty());
|
||||
result
|
||||
(result, tree)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use rustc_infer::traits::{
|
|||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
|
||||
use super::eval_ctxt::GenerateProofTree;
|
||||
use super::{Certainty, InferCtxtEvalExt};
|
||||
|
||||
/// A trait engine using the new trait solver.
|
||||
|
@ -46,8 +47,11 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
|||
self.obligations
|
||||
.drain(..)
|
||||
.map(|obligation| {
|
||||
let code =
|
||||
infcx.probe(|_| match infcx.evaluate_root_goal(obligation.clone().into()) {
|
||||
let code = infcx.probe(|_| {
|
||||
match infcx
|
||||
.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::No)
|
||||
.0
|
||||
{
|
||||
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => {
|
||||
FulfillmentErrorCode::CodeAmbiguity { overflow: false }
|
||||
}
|
||||
|
@ -60,6 +64,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
|||
Err(_) => {
|
||||
bug!("did not expect selection error when collecting ambiguity errors")
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
FulfillmentError {
|
||||
|
@ -81,7 +86,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
|||
let mut has_changed = false;
|
||||
for obligation in mem::take(&mut self.obligations) {
|
||||
let goal = obligation.clone().into();
|
||||
let (changed, certainty, nested_goals) = match infcx.evaluate_root_goal(goal) {
|
||||
let (changed, certainty, nested_goals) =
|
||||
match infcx.evaluate_root_goal(goal, GenerateProofTree::No).0 {
|
||||
Ok(result) => result,
|
||||
Err(NoSolution) => {
|
||||
errors.push(FulfillmentError {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue