diff options
| author | Boxy <supbscripter@gmail.com> | 2023-06-08 23:58:34 +0100 |
|---|---|---|
| committer | Boxy <supbscripter@gmail.com> | 2023-06-19 09:06:16 +0100 |
| commit | 51090b962f10a178f9e15ef445692f6732c9c7ce (patch) | |
| tree | 3c64667dbd599d95f538ae5867e74b223a69c995 | |
| parent | e367c04dc6b23cc09d3bed448450a6c5d19dd254 (diff) | |
| download | rust-51090b962f10a178f9e15ef445692f6732c9c7ce.tar.gz rust-51090b962f10a178f9e15ef445692f6732c9c7ce.zip | |
show normalizes-to hack and response instantiation goals
| -rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/solve/inspect.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/eval_ctxt.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/inspect.rs | 28 |
4 files changed, 71 insertions, 18 deletions
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f0380204970..73959038582 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -991,3 +991,9 @@ pub enum DefiningAnchor { /// Used to catch type mismatch errors when handling opaque types. Error, } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] +pub enum IsNormalizesToHack { + Yes, + No, +} diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs index 0379833d503..d0091d1c30f 100644 --- a/compiler/rustc_middle/src/traits/solve/inspect.rs +++ b/compiler/rustc_middle/src/traits/solve/inspect.rs @@ -1,5 +1,5 @@ use super::{CanonicalInput, Certainty, Goal, NoSolution, QueryInput, QueryResult}; -use crate::ty; +use crate::{traits::IsNormalizesToHack, ty}; use std::fmt::{Debug, Write}; #[derive(Eq, PartialEq, Debug, Hash, HashStable)] @@ -14,6 +14,8 @@ pub struct GoalEvaluation<'tcx> { pub canonicalized_goal: CanonicalInput<'tcx>, pub kind: GoalEvaluationKind<'tcx>, + pub is_normalizes_to_hack: IsNormalizesToHack, + pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, pub result: QueryResult<'tcx>, } @@ -99,7 +101,13 @@ impl ProofTreeFormatter<'_, '_> { fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result { let f = &mut *self.f; - writeln!(f, "GOAL: {:?}", goal.uncanonicalized_goal)?; + + let goal_text = match goal.is_normalizes_to_hack { + IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL", + IsNormalizesToHack::No => "GOAL", + }; + + writeln!(f, "{}: {:?}", goal_text, goal.uncanonicalized_goal,)?; writeln!(f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?; match &goal.kind { @@ -120,7 +128,19 @@ impl ProofTreeFormatter<'_, '_> { let f = &mut *self.f; writeln!(f, "RESULT: {:?}", goal.result) } + }?; + + if goal.returned_goals.len() > 0 { + let f = &mut *self.f; + writeln!(f, "NESTED GOALS ADDED TO CALLER: [")?; + let mut f = self.nested(); + for goal in goal.returned_goals.iter() { + writeln!(f, "ADDED GOAL: {:?},", goal)?; + } + writeln!(self.f, "]")?; } + + Ok(()) } fn format_evaluation_step( diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index c9d531f27ab..9ac37de71d3 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -14,7 +14,7 @@ use rustc_middle::traits::solve::{ CanonicalInput, CanonicalResponse, Certainty, MaybeCause, PredefinedOpaques, PredefinedOpaquesData, QueryResult, }; -use rustc_middle::traits::DefiningAnchor; +use rustc_middle::traits::{DefiningAnchor, IsNormalizesToHack}; use rustc_middle::ty::{ self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -79,12 +79,6 @@ pub struct EvalCtxt<'a, 'tcx> { inspect: ProofTreeBuilder<'tcx>, } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] -pub(super) enum IsNormalizesToHack { - Yes, - No, -} - #[derive(Debug, Clone)] pub(super) struct NestedGoals<'tcx> { /// This normalizes-to goal that is treated specially during the evaluation @@ -262,7 +256,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, ) -> Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> { let (orig_values, canonical_goal) = self.canonicalize_goal(goal); - let mut goal_evaluation = self.inspect.new_goal_evaluation(goal); + let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, is_normalizes_to_hack); let canonical_response = EvalCtxt::evaluate_canonical_goal( self.tcx(), self.search_graph, @@ -270,16 +264,29 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { &mut goal_evaluation, ); goal_evaluation.query_result(canonical_response); - self.inspect.goal_evaluation(goal_evaluation); - let canonical_response = canonical_response?; + let canonical_response = match canonical_response { + Err(e) => { + self.inspect.goal_evaluation(goal_evaluation); + return Err(e); + } + Ok(response) => response, + }; let has_changed = !canonical_response.value.var_values.is_identity() || !canonical_response.value.external_constraints.opaque_types.is_empty(); - let (certainty, nested_goals) = self.instantiate_and_apply_query_response( + let (certainty, nested_goals) = match self.instantiate_and_apply_query_response( goal.param_env, orig_values, canonical_response, - )?; + ) { + Err(e) => { + self.inspect.goal_evaluation(goal_evaluation); + return Err(e); + } + Ok(response) => response, + }; + goal_evaluation.returned_goals(&nested_goals); + self.inspect.goal_evaluation(goal_evaluation); if !has_changed && !nested_goals.is_empty() { bug!("an unchanged goal shouldn't have any side-effects on instantiation"); diff --git a/compiler/rustc_trait_selection/src/solve/inspect.rs b/compiler/rustc_trait_selection/src/solve/inspect.rs index 00c4e631b88..3cba141d9a1 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect.rs @@ -5,6 +5,7 @@ use rustc_middle::{ inspect::{self, CacheHit, CandidateKind}, CanonicalInput, Certainty, Goal, QueryInput, QueryResult, }, + IsNormalizesToHack, }, ty, }; @@ -17,6 +18,8 @@ pub struct WipGoalEvaluation<'tcx> { pub evaluation_steps: Vec<WipGoalEvaluationStep<'tcx>>, pub cache_hit: Option<CacheHit>, + pub is_normalizes_to_hack: IsNormalizesToHack, + pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, pub result: Option<QueryResult<'tcx>>, } @@ -35,6 +38,8 @@ impl<'tcx> WipGoalEvaluation<'tcx> { .collect(), }, }, + is_normalizes_to_hack: self.is_normalizes_to_hack, + returned_goals: self.returned_goals, result: self.result.unwrap(), } } @@ -116,13 +121,11 @@ pub enum DebugSolver<'tcx> { pub struct ProofTreeBuilder<'tcx>(Option<Box<DebugSolver<'tcx>>>); impl<'tcx> ProofTreeBuilder<'tcx> { pub fn finalize(self) -> Option<inspect::GoalEvaluation<'tcx>> { - let wip_tree = *(self.0?); - - match wip_tree { + match *(self.0?) { DebugSolver::GoalEvaluation(wip_goal_evaluation) => { Some(wip_goal_evaluation.finalize()) } - _ => unreachable!(), + root => unreachable!("unexpected proof tree builder root node: {:?}", root), } } @@ -141,6 +144,7 @@ impl<'tcx> ProofTreeBuilder<'tcx> { pub fn new_goal_evaluation( &mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>, + is_normalizes_to_hack: IsNormalizesToHack, ) -> ProofTreeBuilder<'tcx> { if self.0.is_none() { return ProofTreeBuilder(None); @@ -150,7 +154,9 @@ impl<'tcx> ProofTreeBuilder<'tcx> { uncanonicalized_goal: goal, canonicalized_goal: None, evaluation_steps: vec![], + is_normalizes_to_hack, cache_hit: None, + returned_goals: vec![], result: None, })))) } @@ -181,6 +187,20 @@ impl<'tcx> ProofTreeBuilder<'tcx> { _ => unreachable!(), }; } + pub fn returned_goals(&mut self, goals: &[Goal<'tcx, ty::Predicate<'tcx>>]) { + let this = match self.0.as_mut() { + None => return, + Some(this) => &mut **this, + }; + + match this { + DebugSolver::GoalEvaluation(evaluation) => { + assert!(evaluation.returned_goals.is_empty()); + evaluation.returned_goals.extend(goals); + } + _ => unreachable!(), + } + } pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<'tcx>) { let this = match self.0.as_mut() { None => return, |
