Skip to content

Introduce Visitor::BreakTy #651

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
112 changes: 62 additions & 50 deletions chalk-ir/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,24 @@ pub trait Visitor<'i, I: Interner>
where
I: 'i,
{
/// The "break type" of the visitor, often `()`. It represents the result
/// the visitor yields when it stops visiting.
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 +111,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 +132,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 +150,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 +167,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 +190,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 +203,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 +220,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 +240,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 +254,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 +267,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 +284,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 +358,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 +371,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 +399,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 +412,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 +439,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 +452,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 +466,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 +479,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 +492,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