Skip to content

Refactor ProgramClauseData to remove Implies variant #514

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 4 commits into from
Jun 13, 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
2 changes: 1 addition & 1 deletion chalk-integration/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1671,7 +1671,7 @@ impl LowerClause for Clause {
.into_iter()
.map(
|implication: chalk_ir::Binders<chalk_ir::ProgramClauseImplication<ChalkIr>>| {
chalk_ir::ProgramClauseData::ForAll(implication).intern(interner)
chalk_ir::ProgramClauseData(implication).intern(interner)
},
)
.collect();
Expand Down
22 changes: 6 additions & 16 deletions chalk-ir/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,14 @@ where
I: Interner,
{
fn cast_to(self, interner: &I) -> ProgramClause<I> {
ProgramClauseData::Implies(ProgramClauseImplication {
let implication = ProgramClauseImplication {
consequence: self.cast(interner),
conditions: Goals::new(interner),
priority: ClausePriority::High,
})
.intern(interner)
};

ProgramClauseData(Binders::empty(interner, implication.shifted_in(interner)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should make a helper for this -- i.e., for inserting a binders into something with no captures.

But also, this strikes me as a bit dubious. I wonder if in the Cast routines we could, instead of shifting, assert that !implication.needs_shift(interner).

In particular, I feel like we don't normally embed ProgramClauses within other binders, so I wouldn't expect any references to bound variables in outer scopes -- and if there are any, it feels like the "intent" from a cast operation is sort of ambiguous to me.

So I'd be happier if we don't use cast in these cases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That said, it seems like needs_shift needs to be rewritten from a hard-coded helper routine to a method that is available on anything that implements the Visit trait.

.intern(interner)
}
}

Expand All @@ -214,7 +216,7 @@ where
T: HasInterner<Interner = I> + CastTo<DomainGoal<I>>,
{
fn cast_to(self, interner: &I) -> ProgramClause<I> {
ProgramClauseData::ForAll(self.map(|bound| ProgramClauseImplication {
ProgramClauseData(self.map(|bound| ProgramClauseImplication {
consequence: bound.cast(interner),
conditions: Goals::new(interner),
priority: ClausePriority::High,
Expand All @@ -223,18 +225,6 @@ where
}
}

impl<I: Interner> CastTo<ProgramClause<I>> for ProgramClauseImplication<I> {
fn cast_to(self, interner: &I) -> ProgramClause<I> {
ProgramClauseData::Implies(self).intern(interner)
}
}

impl<I: Interner> CastTo<ProgramClause<I>> for Binders<ProgramClauseImplication<I>> {
fn cast_to(self, interner: &I) -> ProgramClause<I> {
ProgramClauseData::ForAll(self).intern(interner)
}
}

impl<T, U> CastTo<Option<U>> for Option<T>
where
T: CastTo<U>,
Expand Down
10 changes: 1 addition & 9 deletions chalk-ir/src/could_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,7 @@ where

impl<I: Interner> CouldMatch<DomainGoal<I>> for ProgramClauseData<I> {
fn could_match(&self, interner: &I, other: &DomainGoal<I>) -> bool {
match self {
ProgramClauseData::Implies(implication) => {
implication.consequence.could_match(interner, other)
}

ProgramClauseData::ForAll(clause) => {
clause.value.consequence.could_match(interner, other)
}
}
self.0.value.consequence.could_match(interner, other)
}
}

Expand Down
5 changes: 1 addition & 4 deletions chalk-ir/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,10 +699,7 @@ impl<T: HasInterner + Debug> Debug for Binders<T> {

impl<I: Interner> Debug for ProgramClauseData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
ProgramClauseData::Implies(pc) => write!(fmt, "{:?}", pc),
ProgramClauseData::ForAll(pc) => write!(fmt, "{:?}", pc),
}
write!(fmt, "{:?}", self.0)
}
}

Expand Down
1 change: 1 addition & 0 deletions chalk-ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod boring_impls;
pub mod shift;
mod subst;

pub use self::shift::Shift;
pub use self::subst::Subst;

/// A "folder" is a transformer that can be used to make a copy of
Expand Down
9 changes: 1 addition & 8 deletions chalk-ir/src/fold/boring_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,7 @@ impl<I: Interner, TI: TargetInterner<I>> SuperFold<I, TI> for ProgramClauseData<
I: 'i,
TI: 'i,
{
match self {
ProgramClauseData::Implies(pci) => Ok(ProgramClauseData::Implies(
pci.fold_with(folder, outer_binder)?,
)),
ProgramClauseData::ForAll(pci) => Ok(ProgramClauseData::ForAll(
pci.fold_with(folder, outer_binder)?,
)),
}
Ok(ProgramClauseData(self.0.fold_with(folder, outer_binder)?))
}
}

Expand Down
14 changes: 2 additions & 12 deletions chalk-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1732,10 +1732,7 @@ impl std::ops::BitAnd for ClausePriority {
}

#[derive(Clone, PartialEq, Eq, Hash, Fold, HasInterner, Zip)]
pub enum ProgramClauseData<I: Interner> {
Implies(ProgramClauseImplication<I>),
ForAll(Binders<ProgramClauseImplication<I>>),
}
pub struct ProgramClauseData<I: Interner>(pub Binders<ProgramClauseImplication<I>>);

impl<I: Interner> ProgramClauseImplication<I> {
pub fn into_from_env_clause(self, interner: &I) -> ProgramClauseImplication<I> {
Expand All @@ -1753,14 +1750,7 @@ impl<I: Interner> ProgramClauseImplication<I> {

impl<I: Interner> ProgramClauseData<I> {
pub fn into_from_env_clause(self, interner: &I) -> ProgramClauseData<I> {
match self {
ProgramClauseData::Implies(implication) => {
ProgramClauseData::Implies(implication.into_from_env_clause(interner))
}
ProgramClauseData::ForAll(binders_implication) => ProgramClauseData::ForAll(
binders_implication.map(|i| i.into_from_env_clause(interner)),
),
}
ProgramClauseData(self.0.map(|i| i.into_from_env_clause(interner)))
}

pub fn intern(self, interner: &I) -> ProgramClause<I> {
Expand Down
11 changes: 4 additions & 7 deletions chalk-ir/src/visit/boring_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

use crate::{
AdtId, AssocTypeId, ClausePriority, DebruijnIndex, FloatTy, FnDefId, GenericArg, Goals, ImplId,
IntTy, Interner, Mutability, OpaqueTyId, PlaceholderIndex, ProgramClause, ProgramClauseData,
ProgramClauses, QuantifiedWhereClauses, QuantifierKind, Scalar, Substitution, SuperVisit,
TraitId, UintTy, UniverseIndex, Visit, VisitResult, Visitor,
IntTy, Interner, Mutability, OpaqueTyId, PlaceholderIndex, ProgramClause, ProgramClauses,
QuantifiedWhereClauses, QuantifierKind, Scalar, Substitution, SuperVisit, TraitId, UintTy,
UniverseIndex, Visit, VisitResult, Visitor,
};
use std::{marker::PhantomData, sync::Arc};

Expand Down Expand Up @@ -247,10 +247,7 @@ impl<I: Interner> SuperVisit<I> for ProgramClause<I> {
{
let interner = visitor.interner();

match self.data(interner) {
ProgramClauseData::Implies(pci) => pci.visit_with(visitor, outer_binder),
ProgramClauseData::ForAll(pci) => pci.visit_with(visitor, outer_binder),
}
self.data(interner).0.visit_with(visitor, outer_binder)
}
}

Expand Down
26 changes: 14 additions & 12 deletions chalk-solve/src/clauses/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::marker::PhantomData;

use crate::cast::{Cast, CastTo};
use crate::RustIrDatabase;
use chalk_ir::fold::Fold;
use chalk_ir::fold::{Fold, Shift};
use chalk_ir::interner::{HasInterner, Interner};
use chalk_ir::*;

Expand Down Expand Up @@ -77,18 +77,20 @@ impl<'me, I: Interner> ClauseBuilder<'me, I> {
priority,
};

if self.binders.len() == 0 {
self.clauses
.push(ProgramClauseData::Implies(clause).intern(interner));
let clause = if self.binders.is_empty() {
// Compensate for the added empty binder
clause.shifted_in(interner)
} else {
self.clauses.push(
ProgramClauseData::ForAll(Binders::new(
VariableKinds::from(interner, self.binders.clone()),
clause,
))
.intern(interner),
);
}
clause
};

self.clauses.push(
ProgramClauseData(Binders::new(
VariableKinds::from(interner, self.binders.clone()),
clause,
))
.intern(interner),
);

debug!("pushed clause {:?}", self.clauses.last());
}
Expand Down
19 changes: 4 additions & 15 deletions chalk-solve/src/recursive/solve.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use super::combine;
use super::fulfill::{Fulfill, RecursiveInferenceTable};
use super::lib::{Guidance, Minimums, Solution, UCanonicalGoal};
use super::Solver;
use crate::clauses::program_clauses_for_goal;
use crate::infer::{InferenceTable, ParameterEnaVariableExt};
use crate::{solve::truncate, RustIrDatabase};
Expand All @@ -13,7 +12,7 @@ use chalk_ir::{debug, debug_heading, info_heading};
use chalk_ir::{
Binders, Canonical, ClausePriority, Constraint, DomainGoal, Environment, Fallible, Floundered,
GenericArg, Goal, GoalData, InEnvironment, NoSolution, ProgramClause, ProgramClauseData,
ProgramClauseImplication, Substitution, UCanonical, UniverseMap, VariableKinds,
ProgramClauseImplication, Substitution, UCanonical, UniverseMap,
};
use std::fmt::Debug;

Expand Down Expand Up @@ -144,19 +143,9 @@ trait SolveIterationHelpers<I: Interner>: SolveDatabase<I> {
return (Ok(Solution::Ambig(Guidance::Unknown)), ClausePriority::High);
}

let res = match program_clause.data(self.interner()) {
ProgramClauseData::Implies(implication) => self.solve_via_implication(
canonical_goal,
&Binders::new(
VariableKinds::from(self.interner(), vec![]),
implication.clone(),
),
minimums,
),
ProgramClauseData::ForAll(implication) => {
self.solve_via_implication(canonical_goal, implication, minimums)
}
};
let ProgramClauseData(implication) = program_clause.data(self.interner());
let res = self.solve_via_implication(canonical_goal, implication, minimums);

if let (Ok(solution), priority) = res {
debug!("ok: solution={:?} prio={:?}", solution, priority);
cur_solution = Some(match cur_solution {
Expand Down
10 changes: 5 additions & 5 deletions chalk-solve/src/solve/slg/resolvent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ impl<I: Interner> context::ResolventOps<I, SlgContext<I>> for TruncatingInferenc
consequence,
conditions,
priority: _,
} = match clause.data(interner) {
ProgramClauseData::Implies(implication) => implication.clone(),
ProgramClauseData::ForAll(implication) => self
.infer
.instantiate_binders_existentially(interner, implication),
} = {
let ProgramClauseData(implication) = clause.data(interner);

self.infer
.instantiate_binders_existentially(interner, implication)
};
debug!("consequence = {:?}", consequence);
debug!("conditions = {:?}", conditions);
Expand Down