Skip to content

Commit 228eb38

Browse files
committed
Convert ProofTreeVisitor to use VisitorResult
1 parent ea9ae30 commit 228eb38

File tree

3 files changed

+28
-31
lines changed

3 files changed

+28
-31
lines changed

compiler/rustc_trait_selection/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#![allow(rustc::untranslatable_diagnostic)]
1919
#![feature(assert_matches)]
2020
#![feature(associated_type_bounds)]
21+
#![feature(associated_type_defaults)]
2122
#![feature(box_patterns)]
2223
#![feature(control_flow_enum)]
2324
#![feature(extract_if)]

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

+23-24
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
/// An infrastructure to mechanically analyse proof trees.
2-
///
3-
/// It is unavoidable that this representation is somewhat
4-
/// lossy as it should hide quite a few semantically relevant things,
5-
/// e.g. canonicalization and the order of nested goals.
6-
///
7-
/// @lcnr: However, a lot of the weirdness here is not strictly necessary
8-
/// and could be improved in the future. This is mostly good enough for
9-
/// coherence right now and was annoying to implement, so I am leaving it
10-
/// as is until we start using it for something else.
11-
use std::ops::ControlFlow;
12-
1+
//! An infrastructure to mechanically analyse proof trees.
2+
//!
3+
//! It is unavoidable that this representation is somewhat
4+
//! lossy as it should hide quite a few semantically relevant things,
5+
//! e.g. canonicalization and the order of nested goals.
6+
//!
7+
//! @lcnr: However, a lot of the weirdness here is not strictly necessary
8+
//! and could be improved in the future. This is mostly good enough for
9+
//! coherence right now and was annoying to implement, so I am leaving it
10+
//! as is until we start using it for something else.
11+
12+
use rustc_ast_ir::try_visit;
13+
use rustc_ast_ir::visit::VisitorResult;
1314
use rustc_infer::infer::InferCtxt;
1415
use rustc_middle::traits::query::NoSolution;
1516
use rustc_middle::traits::solve::{inspect, QueryResult};
@@ -53,10 +54,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
5354
/// to also use it to compute the most relevant goal
5455
/// for fulfillment errors. Will do that once we actually
5556
/// need it.
56-
pub fn visit_nested<V: ProofTreeVisitor<'tcx>>(
57-
&self,
58-
visitor: &mut V,
59-
) -> ControlFlow<V::BreakTy> {
57+
pub fn visit_nested<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
6058
// HACK: An arbitrary cutoff to avoid dealing with overflow and cycles.
6159
if self.goal.depth <= 10 {
6260
let infcx = self.goal.infcx;
@@ -75,17 +73,18 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
7573
for &goal in &instantiated_goals {
7674
let (_, proof_tree) = infcx.evaluate_root_goal(goal, GenerateProofTree::Yes);
7775
let proof_tree = proof_tree.unwrap();
78-
visitor.visit_goal(&InspectGoal::new(
76+
try_visit!(visitor.visit_goal(&InspectGoal::new(
7977
infcx,
8078
self.goal.depth + 1,
8179
&proof_tree,
82-
))?;
80+
)));
8381
}
8482

85-
ControlFlow::Continue(())
86-
})?;
83+
V::Result::output()
84+
})
85+
} else {
86+
V::Result::output()
8787
}
88-
ControlFlow::Continue(())
8988
}
9089
}
9190

@@ -202,9 +201,9 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
202201

203202
/// The public API to interact with proof trees.
204203
pub trait ProofTreeVisitor<'tcx> {
205-
type BreakTy;
204+
type Result: VisitorResult = ();
206205

207-
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy>;
206+
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result;
208207
}
209208

210209
#[extension(pub trait ProofTreeInferCtxtExt<'tcx>)]
@@ -213,7 +212,7 @@ impl<'tcx> InferCtxt<'tcx> {
213212
&self,
214213
goal: Goal<'tcx, ty::Predicate<'tcx>>,
215214
visitor: &mut V,
216-
) -> ControlFlow<V::BreakTy> {
215+
) -> V::Result {
217216
self.probe(|_| {
218217
let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes);
219218
let proof_tree = proof_tree.unwrap();

compiler/rustc_trait_selection/src/traits/coherence.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1023,18 +1023,17 @@ struct AmbiguityCausesVisitor<'a, 'tcx> {
10231023
}
10241024

10251025
impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
1026-
type BreakTy = !;
1027-
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> ControlFlow<Self::BreakTy> {
1026+
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
10281027
let infcx = goal.infcx();
10291028
for cand in goal.candidates() {
1030-
cand.visit_nested(self)?;
1029+
cand.visit_nested(self);
10311030
}
10321031
// When searching for intercrate ambiguity causes, we only need to look
10331032
// at ambiguous goals, as for others the coherence unknowable candidate
10341033
// was irrelevant.
10351034
match goal.result() {
10361035
Ok(Certainty::Maybe(_)) => {}
1037-
Ok(Certainty::Yes) | Err(NoSolution) => return ControlFlow::Continue(()),
1036+
Ok(Certainty::Yes) | Err(NoSolution) => return,
10381037
}
10391038

10401039
let Goal { param_env, predicate } = goal.goal();
@@ -1051,7 +1050,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
10511050
{
10521051
proj.projection_ty.trait_ref(infcx.tcx)
10531052
}
1054-
_ => return ControlFlow::Continue(()),
1053+
_ => return,
10551054
};
10561055

10571056
// Add ambiguity causes for reservation impls.
@@ -1151,8 +1150,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
11511150
if let Some(ambiguity_cause) = ambiguity_cause {
11521151
self.causes.insert(ambiguity_cause);
11531152
}
1154-
1155-
ControlFlow::Continue(())
11561153
}
11571154
}
11581155

0 commit comments

Comments
 (0)