Skip to content

Commit

Permalink
Introduce Visitor::BreakTy
Browse files Browse the repository at this point in the history
  • Loading branch information
LeSeulArtichaut committed Nov 7, 2020
1 parent f2e3fd9 commit d6e34a4
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 128 deletions.
6 changes: 3 additions & 3 deletions chalk-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,11 @@ fn derive_any_visit(
s.bound_impl(
quote!(::chalk_ir::visit:: #trait_name <#interner>),
quote! {
fn #method_name <'i>(
fn #method_name <'i, B>(
&self,
visitor: &mut dyn ::chalk_ir::visit::Visitor < 'i, #interner >,
visitor: &mut dyn ::chalk_ir::visit::Visitor < 'i, #interner, BreakTy = B >,
outer_binder: ::chalk_ir::DebruijnIndex,
) -> ::chalk_ir::visit::ControlFlow<()>
) -> ::chalk_ir::visit::ControlFlow<B>
where
#interner: 'i
{
Expand Down
111 changes: 61 additions & 50 deletions chalk-ir/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,23 @@ pub trait Visitor<'i, I: Interner>
where
I: 'i,
{
/// The "break type" of the visitor.
type BreakTy;

/// Creates a `dyn` value from this visitor. Unfortunately, this
/// must be added manually to each impl of visitor; it permits the
/// default implements below to create a `&mut dyn Visitor` from
/// `Self` without knowing what `Self` is (by invoking this
/// method). Effectively, this limits impls of `visitor` to types
/// for which we are able to create a dyn value (i.e., not `[T]`
/// types).
fn as_dyn(&mut self) -> &mut dyn Visitor<'i, I>;
fn as_dyn(&mut self) -> &mut dyn Visitor<'i, I, BreakTy = Self::BreakTy>;

/// Top-level callback: invoked for each `Ty<I>` that is
/// encountered when visiting. By default, invokes
/// `super_visit_with`, which will in turn invoke the more
/// specialized visiting methods below, like `visit_free_var`.
fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
fn visit_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
ty.super_visit_with(self.as_dyn(), outer_binder)
}

Expand All @@ -107,15 +110,19 @@ where
&mut self,
lifetime: &Lifetime<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
lifetime.super_visit_with(self.as_dyn(), outer_binder)
}

/// Top-level callback: invoked for each `Const<I>` that is
/// encountered when visiting. By default, invokes
/// `super_visit_with`, which will in turn invoke the more
/// specialized visiting methods below, like `visit_free_var`.
fn visit_const(&mut self, constant: &Const<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
fn visit_const(
&mut self,
constant: &Const<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<Self::BreakTy> {
constant.super_visit_with(self.as_dyn(), outer_binder)
}

Expand All @@ -124,12 +131,16 @@ where
&mut self,
clause: &ProgramClause<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
clause.super_visit_with(self.as_dyn(), outer_binder)
}

/// Invoked for every goal. By default, recursively visits the goals contents.
fn visit_goal(&mut self, goal: &Goal<I>, outer_binder: DebruijnIndex) -> ControlFlow<()> {
fn visit_goal(
&mut self,
goal: &Goal<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<Self::BreakTy> {
goal.super_visit_with(self.as_dyn(), outer_binder)
}

Expand All @@ -138,7 +149,7 @@ where
&mut self,
domain_goal: &DomainGoal<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
domain_goal.super_visit_with(self.as_dyn(), outer_binder)
}

Expand All @@ -155,7 +166,7 @@ where
&mut self,
bound_var: BoundVar,
outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
if self.forbid_free_vars() {
panic!(
"unexpected free variable `{:?}` with outer binder {:?}",
Expand All @@ -178,7 +189,7 @@ where
&mut self,
universe: PlaceholderIndex,
_outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
if self.forbid_free_placeholders() {
panic!("unexpected placeholder type `{:?}`", universe)
} else {
Expand All @@ -191,7 +202,7 @@ where
&mut self,
where_clause: &WhereClause<I>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
where_clause.super_visit_with(self.as_dyn(), outer_binder)
}

Expand All @@ -208,7 +219,7 @@ where
&mut self,
var: InferenceVar,
_outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
) -> ControlFlow<Self::BreakTy> {
if self.forbid_inference_vars() {
panic!("unexpected inference type `{:?}`", var)
} else {
Expand All @@ -228,11 +239,11 @@ pub trait Visit<I: Interner>: Debug {
/// visitor. Typically `binders` starts as 0, but is adjusted when
/// we encounter `Binders<T>` in the IR or other similar
/// constructs.
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i;
}
Expand All @@ -242,11 +253,11 @@ pub trait Visit<I: Interner>: Debug {
/// the contents of the type.
pub trait SuperVisit<I: Interner>: Visit<I> {
/// Recursively visits the type contents.
fn super_visit_with<'i>(
fn super_visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i;
}
Expand All @@ -255,11 +266,11 @@ pub trait SuperVisit<I: Interner>: Visit<I> {
/// usually (in turn) invokes `super_visit_ty` to visit the individual
/// parts.
impl<I: Interner> Visit<I> for Ty<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -272,11 +283,11 @@ impl<I> SuperVisit<I> for Ty<I>
where
I: Interner,
{
fn super_visit_with<'i>(
fn super_visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand Down Expand Up @@ -346,11 +357,11 @@ where
}

impl<I: Interner> Visit<I> for Lifetime<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -359,11 +370,11 @@ impl<I: Interner> Visit<I> for Lifetime<I> {
}

impl<I: Interner> SuperVisit<I> for Lifetime<I> {
fn super_visit_with<'i>(
fn super_visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -387,11 +398,11 @@ impl<I: Interner> SuperVisit<I> for Lifetime<I> {
}

impl<I: Interner> Visit<I> for Const<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -400,11 +411,11 @@ impl<I: Interner> Visit<I> for Const<I> {
}

impl<I: Interner> SuperVisit<I> for Const<I> {
fn super_visit_with<'i>(
fn super_visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -427,11 +438,11 @@ impl<I: Interner> SuperVisit<I> for Const<I> {
}

impl<I: Interner> Visit<I> for Goal<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -440,11 +451,11 @@ impl<I: Interner> Visit<I> for Goal<I> {
}

impl<I: Interner> SuperVisit<I> for Goal<I> {
fn super_visit_with<'i>(
fn super_visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -454,11 +465,11 @@ impl<I: Interner> SuperVisit<I> for Goal<I> {
}

impl<I: Interner> Visit<I> for ProgramClause<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -467,11 +478,11 @@ impl<I: Interner> Visit<I> for ProgramClause<I> {
}

impl<I: Interner> Visit<I> for WhereClause<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -480,11 +491,11 @@ impl<I: Interner> Visit<I> for WhereClause<I> {
}

impl<I: Interner> Visit<I> for DomainGoal<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand Down
18 changes: 9 additions & 9 deletions chalk-ir/src/visit/binder_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use crate::interner::HasInterner;
use crate::{Binders, Canonical, ControlFlow, DebruijnIndex, FnPointer, Interner, Visit, Visitor};

impl<I: Interner> Visit<I> for FnPointer<I> {
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -26,11 +26,11 @@ impl<T, I: Interner> Visit<I> for Binders<T>
where
T: HasInterner + Visit<I>,
{
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand All @@ -43,11 +43,11 @@ where
I: Interner,
T: HasInterner<Interner = I> + Visit<I>,
{
fn visit_with<'i>(
fn visit_with<'i, B>(
&self,
visitor: &mut dyn Visitor<'i, I>,
visitor: &mut dyn Visitor<'i, I, BreakTy = B>,
outer_binder: DebruijnIndex,
) -> ControlFlow<()>
) -> ControlFlow<B>
where
I: 'i,
{
Expand Down
Loading

0 comments on commit d6e34a4

Please sign in to comment.