Skip to content

Replace ControlFlow with version in std #729

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
Oct 3, 2021
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
4 changes: 2 additions & 2 deletions chalk-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,14 @@ fn derive_any_visit(
&self,
visitor: &mut dyn ::chalk_ir::visit::Visitor < 'i, #interner, BreakTy = B >,
outer_binder: ::chalk_ir::DebruijnIndex,
) -> ::chalk_ir::visit::ControlFlow<B>
) -> std::ops::ControlFlow<B>
where
#interner: 'i
{
match *self {
#body
}
::chalk_ir::visit::ControlFlow::CONTINUE
std::ops::ControlFlow::Continue(())
}
},
)
Expand Down
2 changes: 1 addition & 1 deletion chalk-engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ use std::usize;

use chalk_derive::{Fold, HasInterner, Visit};
use chalk_ir::interner::Interner;
use chalk_ir::visit::ControlFlow;
use chalk_ir::{
AnswerSubst, Canonical, ConstrainedSubst, Constraint, DebruijnIndex, Goal, InEnvironment,
Substitution,
};
use std::ops::ControlFlow;

pub mod context;
mod derived;
Expand Down
3 changes: 2 additions & 1 deletion chalk-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ extern crate self as chalk_ir;
use crate::cast::{Cast, CastTo, Caster};
use crate::fold::shift::Shift;
use crate::fold::{Fold, Folder, Subst, SuperFold};
use crate::visit::{ControlFlow, SuperVisit, Visit, VisitExt, Visitor};
use crate::visit::{SuperVisit, Visit, VisitExt, Visitor};
use chalk_derive::{Fold, HasInterner, SuperVisit, Visit, Zip};
use std::marker::PhantomData;
use std::ops::ControlFlow;

pub use crate::debug::SeparatorTraitRef;
#[macro_use(bitflags)]
Expand Down
71 changes: 14 additions & 57 deletions chalk-ir/src/visit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Traits for visiting bits of IR.
use std::fmt::Debug;
use std::ops::ControlFlow;

use crate::{
BoundVar, Const, ConstValue, DebruijnIndex, DomainGoal, Goal, InferenceVar, Interner, Lifetime,
Expand All @@ -12,59 +13,15 @@ pub mod visitors;

pub use visitors::VisitExt;

/// An copy of the unstable `std::ops::ControlFlow` for use in Chalk visitors.
pub enum ControlFlow<B, C = ()> {
/// Continue in the loop, using the given value for the next iteration
Continue(C),
/// Exit the loop, yielding the given value
Break(B),
}

impl<B, C> ControlFlow<B, C> {
/// Returns `true` if this is a `Break` variant.
#[inline]
pub fn is_break(&self) -> bool {
matches!(*self, ControlFlow::Break(_))
}

/// Returns `true` if this is a `Continue` variant.
#[inline]
pub fn is_continue(&self) -> bool {
matches!(*self, ControlFlow::Continue(_))
}

/// Converts the `ControlFlow` into an `Option` which is `Some`
/// if the `ControlFlow` was `Break` and `None` otherwise.
#[inline]
pub fn break_value(self) -> Option<B> {
match self {
ControlFlow::Continue(..) => None,
ControlFlow::Break(x) => Some(x),
}
}
}

impl<B> ControlFlow<B, ()> {
/// It's frequently the case that there's no value needed with `Continue`,
/// so this provides a way to avoid typing `(())`, if you prefer it.
pub const CONTINUE: Self = ControlFlow::Continue(());
}

impl<C> ControlFlow<(), C> {
/// APIs like `try_for_each` don't need values with `Break`,
/// so this provides a way to avoid typing `(())`, if you prefer it.
pub const BREAK: Self = ControlFlow::Break(());
}

/// Unwraps a `ControlFlow` or propagates its `Break` value.
/// This replaces the `Try` implementation that would be used
/// with `std::ops::ControlFlow`.
#[macro_export]
macro_rules! try_break {
($expr:expr) => {
match $expr {
$crate::visit::ControlFlow::Continue(c) => c,
$crate::visit::ControlFlow::Break(b) => return $crate::visit::ControlFlow::Break(b),
std::ops::ControlFlow::Continue(c) => c,
std::ops::ControlFlow::Break(b) => return std::ops::ControlFlow::Break(b),
}
};
}
Expand Down Expand Up @@ -174,7 +131,7 @@ where
bound_var, outer_binder
)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}

Expand All @@ -194,7 +151,7 @@ where
if self.forbid_free_placeholders() {
panic!("unexpected placeholder type `{:?}`", universe)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}

Expand Down Expand Up @@ -224,7 +181,7 @@ where
if self.forbid_inference_vars() {
panic!("unexpected inference type `{:?}`", var)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}

Expand Down Expand Up @@ -298,7 +255,7 @@ where
if let Some(_) = bound_var.shifted_out_to(outer_binder) {
visitor.visit_free_var(*bound_var, outer_binder)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
TyKind::Dyn(clauses) => clauses.visit_with(visitor, outer_binder),
Expand All @@ -311,7 +268,7 @@ where
substitution.visit_with(visitor, outer_binder)
}
TyKind::Scalar(scalar) => scalar.visit_with(visitor, outer_binder),
TyKind::Str => ControlFlow::CONTINUE,
TyKind::Str => ControlFlow::Continue(()),
TyKind::Tuple(arity, substitution) => {
try_break!(arity.visit_with(visitor, outer_binder));
substitution.visit_with(visitor, outer_binder)
Expand All @@ -334,7 +291,7 @@ where
try_break!(mutability.visit_with(visitor, outer_binder));
ty.visit_with(visitor, outer_binder)
}
TyKind::Never => ControlFlow::CONTINUE,
TyKind::Never => ControlFlow::Continue(()),
TyKind::Array(ty, const_) => {
try_break!(ty.visit_with(visitor, outer_binder));
const_.visit_with(visitor, outer_binder)
Expand All @@ -352,7 +309,7 @@ where
substitution.visit_with(visitor, outer_binder)
}
TyKind::Foreign(foreign_ty) => foreign_ty.visit_with(visitor, outer_binder),
TyKind::Error => ControlFlow::CONTINUE,
TyKind::Error => ControlFlow::Continue(()),
}
}
}
Expand Down Expand Up @@ -385,15 +342,15 @@ impl<I: Interner> SuperVisit<I> for Lifetime<I> {
if let Some(_) = bound_var.shifted_out_to(outer_binder) {
visitor.visit_free_var(*bound_var, outer_binder)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
LifetimeData::InferenceVar(var) => visitor.visit_inference_var(*var, outer_binder),
LifetimeData::Placeholder(universe) => {
visitor.visit_free_placeholder(*universe, outer_binder)
}
LifetimeData::Static | LifetimeData::Empty(_) | LifetimeData::Erased => {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
LifetimeData::Phantom(void, ..) => match *void {},
}
Expand Down Expand Up @@ -428,14 +385,14 @@ impl<I: Interner> SuperVisit<I> for Const<I> {
if let Some(_) = bound_var.shifted_out_to(outer_binder) {
visitor.visit_free_var(*bound_var, outer_binder)
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
ConstValue::InferenceVar(var) => visitor.visit_inference_var(*var, outer_binder),
ConstValue::Placeholder(universe) => {
visitor.visit_free_placeholder(*universe, outer_binder)
}
ConstValue::Concrete(_) => ControlFlow::CONTINUE,
ConstValue::Concrete(_) => ControlFlow::Continue(()),
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions chalk-ir/src/visit/boring_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ where
for e in it {
try_break!(e.visit_with(visitor, outer_binder));
}
ControlFlow::CONTINUE
ControlFlow::Continue(())
}

impl<T: Visit<I>, I: Interner> Visit<I> for &T {
Expand Down Expand Up @@ -104,7 +104,7 @@ macro_rules! tuple_visit {
$(
try_break!($n.visit_with(visitor, outer_binder));
)*
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
}
Expand All @@ -126,7 +126,7 @@ impl<T: Visit<I>, I: Interner> Visit<I> for Option<T> {
{
match self {
Some(e) => e.visit_with(visitor, outer_binder),
None => ControlFlow::CONTINUE,
None => ControlFlow::Continue(()),
}
}
}
Expand Down Expand Up @@ -186,7 +186,7 @@ macro_rules! const_visit {
where
I: 'i,
{
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
};
Expand Down Expand Up @@ -220,7 +220,7 @@ macro_rules! id_visit {
where
I: 'i,
{
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
};
Expand Down Expand Up @@ -305,6 +305,6 @@ impl<I: Interner> Visit<I> for PhantomData<I> {
where
I: 'i,
{
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
8 changes: 4 additions & 4 deletions chalk-ir/src/visit/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use crate::{BoundVar, ControlFlow, DebruijnIndex, Interner, Visit, Visitor};
pub trait VisitExt<I: Interner>: Visit<I> {
/// Check whether there are free (non-bound) variables.
fn has_free_vars(&self, interner: &I) -> bool {
self.visit_with(
let flow = self.visit_with(
&mut FindFreeVarsVisitor { interner },
DebruijnIndex::INNERMOST,
)
.is_break()
);
matches!(flow, ControlFlow::Break(_))
}
}

Expand All @@ -36,6 +36,6 @@ impl<'i, I: Interner> Visitor<'i, I> for FindFreeVarsVisitor<'i, I> {
_bound_var: BoundVar,
_outer_binder: DebruijnIndex,
) -> ControlFlow<()> {
ControlFlow::BREAK
ControlFlow::Break(())
}
}
22 changes: 12 additions & 10 deletions chalk-solve/src/clauses/builtin_traits/unsize.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use std::collections::HashSet;
use std::iter;
use std::ops::ControlFlow;

use crate::clauses::ClauseBuilder;
use crate::rust_ir::AdtKind;
use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait};
use chalk_ir::{
cast::Cast,
interner::HasInterner,
visit::{ControlFlow, SuperVisit, Visit, Visitor},
visit::{SuperVisit, Visit, Visitor},
Binders, Const, ConstValue, DebruijnIndex, DomainGoal, DynTy, EqGoal, Goal, LifetimeOutlives,
QuantifiedWhereClauses, Substitution, TraitId, Ty, TyKind, TypeOutlives, WhereClause,
};
Expand All @@ -34,7 +35,7 @@ impl<'a, I: Interner> Visitor<'a, I> for UnsizeParameterCollector<'a, I> {
if bound_var.debruijn.shifted_in() == outer_binder {
self.parameters.insert(bound_var.index);
}
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
_ => ty.super_visit_with(self, outer_binder),
}
Expand All @@ -49,7 +50,7 @@ impl<'a, I: Interner> Visitor<'a, I> for UnsizeParameterCollector<'a, I> {
self.parameters.insert(bound_var.index);
}
}
ControlFlow::CONTINUE
ControlFlow::Continue(())
}

fn interner(&self) -> &'a I {
Expand Down Expand Up @@ -90,9 +91,9 @@ impl<'a, 'p, I: Interner> Visitor<'a, I> for ParameterOccurenceCheck<'a, 'p, I>
if bound_var.debruijn.shifted_in() == outer_binder
&& self.parameters.contains(&bound_var.index)
{
ControlFlow::BREAK
ControlFlow::Break(())
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
_ => ty.super_visit_with(self, outer_binder),
Expand All @@ -107,12 +108,12 @@ impl<'a, 'p, I: Interner> Visitor<'a, I> for ParameterOccurenceCheck<'a, 'p, I>
if bound_var.debruijn.shifted_in() == outer_binder
&& self.parameters.contains(&bound_var.index)
{
ControlFlow::BREAK
ControlFlow::Break(())
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
_ => ControlFlow::CONTINUE,
_ => ControlFlow::Continue(()),
}
}

Expand All @@ -130,8 +131,9 @@ fn uses_outer_binder_params<I: Interner>(
interner,
parameters,
};
v.visit_with(&mut visitor, DebruijnIndex::INNERMOST)
.is_break()

let flow = v.visit_with(&mut visitor, DebruijnIndex::INNERMOST);
matches!(flow, ControlFlow::Break(_))
}

fn principal_id<'a, I: Interner>(
Expand Down
9 changes: 5 additions & 4 deletions chalk-solve/src/clauses/env_elaborator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use crate::RustIrDatabase;
use crate::Ty;
use crate::{debug_span, TyKind};
use chalk_ir::interner::Interner;
use chalk_ir::visit::{ControlFlow, Visit, Visitor};
use chalk_ir::visit::{Visit, Visitor};
use chalk_ir::{DebruijnIndex, Environment};
use rustc_hash::FxHashSet;
use std::ops::ControlFlow;
use tracing::instrument;

/// When proving a `FromEnv` goal, we elaborate all `FromEnv` goals
Expand Down Expand Up @@ -71,7 +72,7 @@ impl<'me, 'builder, I: Interner> Visitor<'me, I> for EnvElaborator<'me, 'builder
.unwrap()
}
}
ControlFlow::CONTINUE
ControlFlow::Continue(())
}

fn visit_domain_goal(
Expand All @@ -95,12 +96,12 @@ impl<'me, 'builder, I: Interner> Visitor<'me, I> for EnvElaborator<'me, 'builder
.associated_ty_data(associated_ty_id)
.to_program_clauses(self.builder, self.environment);
}
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
FromEnv::Ty(ty) => ty.visit_with(self, outer_binder),
}
} else {
ControlFlow::CONTINUE
ControlFlow::Continue(())
}
}
}
Loading