diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2024-02-24 19:38:58 -0500 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2024-03-05 13:30:49 -0500 |
| commit | 228eb38c6951ea5d0da2830f278422ad912f8795 (patch) | |
| tree | 0f86fa0ddb4eef4ce827303b884e122106649ba5 | |
| parent | ea9ae30671f5bc42c4af392e5556dd16be297e82 (diff) | |
| download | rust-228eb38c6951ea5d0da2830f278422ad912f8795.tar.gz rust-228eb38c6951ea5d0da2830f278422ad912f8795.zip | |
Convert `ProofTreeVisitor` to use `VisitorResult`
| -rw-r--r-- | compiler/rustc_trait_selection/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 47 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 11 |
3 files changed, 28 insertions, 31 deletions
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 7c1bfebef2c..fd3d62d1321 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -18,6 +18,7 @@ #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] #![feature(associated_type_bounds)] +#![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extract_if)] diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 52b900af853..9e3e6a4676e 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -1,15 +1,16 @@ -/// An infrastructure to mechanically analyse proof trees. -/// -/// It is unavoidable that this representation is somewhat -/// lossy as it should hide quite a few semantically relevant things, -/// e.g. canonicalization and the order of nested goals. -/// -/// @lcnr: However, a lot of the weirdness here is not strictly necessary -/// and could be improved in the future. This is mostly good enough for -/// coherence right now and was annoying to implement, so I am leaving it -/// as is until we start using it for something else. -use std::ops::ControlFlow; - +//! An infrastructure to mechanically analyse proof trees. +//! +//! It is unavoidable that this representation is somewhat +//! lossy as it should hide quite a few semantically relevant things, +//! e.g. canonicalization and the order of nested goals. +//! +//! @lcnr: However, a lot of the weirdness here is not strictly necessary +//! and could be improved in the future. This is mostly good enough for +//! coherence right now and was annoying to implement, so I am leaving it +//! as is until we start using it for something else. + +use rustc_ast_ir::try_visit; +use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::InferCtxt; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{inspect, QueryResult}; @@ -53,10 +54,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { /// to also use it to compute the most relevant goal /// for fulfillment errors. Will do that once we actually /// need it. - pub fn visit_nested<V: ProofTreeVisitor<'tcx>>( - &self, - visitor: &mut V, - ) -> ControlFlow<V::BreakTy> { + pub fn visit_nested<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result { // HACK: An arbitrary cutoff to avoid dealing with overflow and cycles. if self.goal.depth <= 10 { let infcx = self.goal.infcx; @@ -75,17 +73,18 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { for &goal in &instantiated_goals { let (_, proof_tree) = infcx.evaluate_root_goal(goal, GenerateProofTree::Yes); let proof_tree = proof_tree.unwrap(); - visitor.visit_goal(&InspectGoal::new( + try_visit!(visitor.visit_goal(&InspectGoal::new( infcx, self.goal.depth + 1, &proof_tree, - ))?; + ))); } - ControlFlow::Continue(()) - })?; + V::Result::output() + }) + } else { + V::Result::output() } - ControlFlow::Continue(()) } } @@ -202,9 +201,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { /// The public API to interact with proof trees. pub trait ProofTreeVisitor<'tcx> { - type BreakTy; + type Result: VisitorResult = (); - fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy>; + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result; } #[extension(pub trait ProofTreeInferCtxtExt<'tcx>)] @@ -213,7 +212,7 @@ impl<'tcx> InferCtxt<'tcx> { &self, goal: Goal<'tcx, ty::Predicate<'tcx>>, visitor: &mut V, - ) -> ControlFlow<V::BreakTy> { + ) -> V::Result { self.probe(|_| { let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); let proof_tree = proof_tree.unwrap(); diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 20af016eb00..176647a4b15 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -1023,18 +1023,17 @@ struct AmbiguityCausesVisitor<'a, 'tcx> { } impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { - type BreakTy = !; - fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy> { + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) { let infcx = goal.infcx(); for cand in goal.candidates() { - cand.visit_nested(self)?; + cand.visit_nested(self); } // When searching for intercrate ambiguity causes, we only need to look // at ambiguous goals, as for others the coherence unknowable candidate // was irrelevant. match goal.result() { Ok(Certainty::Maybe(_)) => {} - Ok(Certainty::Yes) | Err(NoSolution) => return ControlFlow::Continue(()), + Ok(Certainty::Yes) | Err(NoSolution) => return, } let Goal { param_env, predicate } = goal.goal(); @@ -1051,7 +1050,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { { proj.projection_ty.trait_ref(infcx.tcx) } - _ => return ControlFlow::Continue(()), + _ => return, }; // Add ambiguity causes for reservation impls. @@ -1151,8 +1150,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { if let Some(ambiguity_cause) = ambiguity_cause { self.causes.insert(ambiguity_cause); } - - ControlFlow::Continue(()) } } |
