Skip to content

Commit eac7a6c

Browse files
authored
Merge pull request #36 from aturon/maybe-subst
Use substitutions and suggestions in Solution; implement negation
2 parents 8b0bc97 + d3e941e commit eac7a6c

29 files changed

+4096
-3604
lines changed

chalk-parse/src/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ pub enum Goal {
164164
Exists(Vec<ParameterKind>, Box<Goal>),
165165
Implies(Vec<WhereClause>, Box<Goal>),
166166
And(Box<Goal>, Box<Goal>),
167+
Not(Box<Goal>),
167168

168169
// Additional kinds of goals:
169170
Leaf(WhereClause),

chalk-parse/src/parser.lalrpop

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Goal1: Box<Goal> = {
2929
"forall" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::ForAll(p, g)),
3030
"exists" "<" <p:Comma<ParameterKind>> ">" "{" <g:Goal> "}" => Box::new(Goal::Exists(p, g)),
3131
"if" "(" <w:Comma<WhereClause>> ")" "{" <g:Goal> "}" => Box::new(Goal::Implies(w, g)),
32+
"not" "{" <g:Goal> "}" => Box::new(Goal::Not(g)),
3233
<w:WhereClause> => Box::new(Goal::Leaf(w)),
3334
};
3435

chalk-parse/src/parser.rs

+2,522-2,264
Large diffs are not rendered by default.

src/bin/repl.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::sync::Arc;
1111

1212
use chalk::ir;
1313
use chalk::lower::*;
14-
use chalk::solve::prove::Prove;
1514
use chalk::solve::solver::Solver;
1615

1716
use rustyline::error::ReadlineError;
@@ -121,9 +120,13 @@ fn goal(text: &str, prog: &Program) -> Result<()> {
121120
let goal = chalk_parse::parse_goal(text)?.lower(&*prog.ir)?;
122121
let overflow_depth = 10;
123122
let mut solver = Solver::new(&prog.env, overflow_depth);
124-
match Prove::new(&mut solver, goal).solve() {
125-
Ok(v) => println!("{:#?}", v),
126-
Err(e) => println!("{}", e),
123+
let goal = ir::Canonical {
124+
value: ir::InEnvironment::new(&ir::Environment::new(), *goal),
125+
binders: vec![],
126+
};
127+
match solver.solve_goal(goal) {
128+
Ok(v) => println!("{}\n", v),
129+
Err(e) => println!("No possible solution: {}\n", e),
127130
}
128131
Ok(())
129132
}

src/cast.rs

+34-40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use ir::*;
2-
use solve::Solution;
32

43
pub trait Cast<T>: Sized {
54
fn cast(self) -> T;
@@ -23,59 +22,62 @@ macro_rules! reflexive_impl {
2322
}
2423

2524
reflexive_impl!(TraitRef);
26-
reflexive_impl!(WhereClause);
27-
reflexive_impl!(WhereClauseGoal);
25+
reflexive_impl!(LeafGoal);
26+
reflexive_impl!(DomainGoal);
2827

29-
impl Cast<WhereClause> for TraitRef {
30-
fn cast(self) -> WhereClause {
31-
WhereClause::Implemented(self)
28+
impl Cast<DomainGoal> for TraitRef {
29+
fn cast(self) -> DomainGoal {
30+
DomainGoal::Implemented(self)
3231
}
3332
}
3433

35-
impl Cast<WhereClauseGoal> for TraitRef {
36-
fn cast(self) -> WhereClauseGoal {
37-
WhereClauseGoal::Implemented(self)
34+
impl Cast<LeafGoal> for TraitRef {
35+
fn cast(self) -> LeafGoal {
36+
LeafGoal::DomainGoal(self.cast())
3837
}
3938
}
4039

41-
impl Cast<WhereClause> for Normalize {
42-
fn cast(self) -> WhereClause {
43-
WhereClause::Normalize(self)
40+
impl Cast<DomainGoal> for Normalize {
41+
fn cast(self) -> DomainGoal {
42+
DomainGoal::Normalize(self)
4443
}
4544
}
4645

47-
impl Cast<WhereClauseGoal> for Normalize {
48-
fn cast(self) -> WhereClauseGoal {
49-
WhereClauseGoal::Normalize(self)
46+
impl Cast<LeafGoal> for Normalize {
47+
fn cast(self) -> LeafGoal {
48+
LeafGoal::DomainGoal(self.cast())
5049
}
5150
}
5251

53-
impl Cast<WhereClauseGoal> for WellFormed {
54-
fn cast(self) -> WhereClauseGoal {
55-
WhereClauseGoal::WellFormed(self)
52+
impl Cast<DomainGoal> for WellFormed {
53+
fn cast(self) -> DomainGoal {
54+
DomainGoal::WellFormed(self)
55+
}
56+
}
57+
58+
impl Cast<LeafGoal> for WellFormed {
59+
fn cast(self) -> LeafGoal {
60+
LeafGoal::DomainGoal(self.cast())
5661
}
5762
}
5863

5964
impl Cast<Goal> for WellFormed {
6065
fn cast(self) -> Goal {
61-
let wcg: WhereClauseGoal = self.cast();
66+
let wcg: LeafGoal = self.cast();
6267
wcg.cast()
6368
}
6469
}
6570

6671
impl Cast<Goal> for Normalize {
6772
fn cast(self) -> Goal {
68-
let wcg: WhereClauseGoal = self.cast();
73+
let wcg: LeafGoal = self.cast();
6974
wcg.cast()
7075
}
7176
}
7277

73-
impl Cast<WhereClauseGoal> for WhereClause {
74-
fn cast(self) -> WhereClauseGoal {
75-
match self {
76-
WhereClause::Implemented(a) => a.cast(),
77-
WhereClause::Normalize(a) => a.cast(),
78-
}
78+
impl Cast<LeafGoal> for DomainGoal {
79+
fn cast(self) -> LeafGoal {
80+
LeafGoal::DomainGoal(self)
7981
}
8082
}
8183

@@ -85,27 +87,21 @@ impl Cast<Goal> for TraitRef {
8587
}
8688
}
8789

88-
impl Cast<Goal> for WhereClause {
90+
impl Cast<Goal> for DomainGoal {
8991
fn cast(self) -> Goal {
9092
Goal::Leaf(self.cast())
9193
}
9294
}
9395

94-
impl Cast<Goal> for WhereClauseGoal {
96+
impl Cast<Goal> for LeafGoal {
9597
fn cast(self) -> Goal {
9698
Goal::Leaf(self)
9799
}
98100
}
99101

100-
impl Cast<WhereClauseGoal> for Unify<Ty> {
101-
fn cast(self) -> WhereClauseGoal {
102-
WhereClauseGoal::UnifyTys(self)
103-
}
104-
}
105-
106-
impl Cast<WhereClauseGoal> for Unify<Lifetime> {
107-
fn cast(self) -> WhereClauseGoal {
108-
WhereClauseGoal::UnifyLifetimes(self)
102+
impl Cast<LeafGoal> for EqGoal {
103+
fn cast(self) -> LeafGoal {
104+
LeafGoal::EqGoal(self)
109105
}
110106
}
111107

@@ -126,10 +122,8 @@ macro_rules! map_impl {
126122
}
127123

128124
map_impl!(impl[T: Cast<U>, U] Cast<Option<U>> for Option<T>);
129-
map_impl!(impl[T: Cast<U>, U] Cast<Query<U>> for Query<T>);
130-
map_impl!(impl[T: Cast<U>, U] Cast<Solution<U>> for Solution<T>);
125+
map_impl!(impl[T: Cast<U>, U] Cast<Canonical<U>> for Canonical<T>);
131126
map_impl!(impl[T: Cast<U>, U] Cast<InEnvironment<U>> for InEnvironment<T>);
132-
map_impl!(impl[T: Cast<U>, U] Cast<Constrained<U>> for Constrained<T>);
133127
map_impl!(impl[T: Cast<U>, U, E] Cast<Result<U, E>> for Result<T, E>);
134128

135129
impl<T, U> Cast<Vec<U>> for Vec<T>

src/fold/mod.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use errors::*;
22
use ir::*;
33
use std::fmt::Debug;
44
use std::sync::Arc;
5+
use std::collections::BTreeMap;
56

67
mod instantiate;
78
mod shifted;
@@ -139,6 +140,23 @@ impl Fold for Lifetime {
139140
}
140141
}
141142

143+
impl Fold for Substitution {
144+
type Result = Substitution;
145+
fn fold_with(&self, folder: &mut Folder, binders: usize) -> Result<Self::Result> {
146+
let mut tys = BTreeMap::new();
147+
let mut lifetimes = BTreeMap::new();
148+
149+
for (var, ty) in &self.tys {
150+
tys.insert(*var, ty.fold_with(folder, binders)?);
151+
}
152+
for (var, lt) in &self.lifetimes {
153+
lifetimes.insert(*var, lt.fold_with(folder, binders)?);
154+
}
155+
156+
Ok(Substitution { tys, lifetimes })
157+
}
158+
}
159+
142160
macro_rules! copy_fold {
143161
($t:ty) => {
144162
impl Fold for $t {
@@ -178,12 +196,11 @@ macro_rules! enum_fold {
178196
}
179197

180198
enum_fold!(ParameterKind[T,L] { Ty(a), Lifetime(a) } where T: Fold, L: Fold);
181-
enum_fold!(WhereClause[] { Implemented(a), Normalize(a) });
199+
enum_fold!(DomainGoal[] { Implemented(a), RawNormalize(a), Normalize(a), WellFormed(a) });
182200
enum_fold!(WellFormed[] { Ty(a), TraitRef(a) });
183-
enum_fold!(WhereClauseGoal[] { Implemented(a), Normalize(a), UnifyTys(a),
184-
UnifyLifetimes(a), WellFormed(a) });
201+
enum_fold!(LeafGoal[] { EqGoal(a), DomainGoal(a) });
185202
enum_fold!(Constraint[] { LifetimeEq(a, b) });
186-
enum_fold!(Goal[] { Quantified(qkind, subgoal), Implies(wc, subgoal), And(g1, g2), Leaf(wc) });
203+
enum_fold!(Goal[] { Quantified(qkind, subgoal), Implies(wc, subgoal), And(g1, g2), Not(g), Leaf(wc) });
187204

188205
macro_rules! struct_fold {
189206
($s:ident $([$($n:ident),*])* { $($name:ident),* } $($w:tt)*) => {
@@ -206,6 +223,6 @@ struct_fold!(AssociatedTyValue { associated_ty_id, value });
206223
struct_fold!(AssociatedTyValueBound { ty, where_clauses });
207224
struct_fold!(Environment { universe, clauses });
208225
struct_fold!(InEnvironment[F] { environment, goal } where F: Fold);
209-
struct_fold!(Unify[T] { a, b } where T: Fold);
210-
struct_fold!(Constrained[F] { value, constraints } where F: Fold);
226+
struct_fold!(EqGoal { a, b });
211227
struct_fold!(ProgramClauseImplication { consequence, conditions });
228+
struct_fold!(ConstrainedSubst { subst, constraints });

src/fold/shifter.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ up_shift_method!(Ty);
3434
up_shift_method!(Parameter);
3535
up_shift_method!(Lifetime);
3636
up_shift_method!(TraitRef);
37+
up_shift_method!(ProjectionTy);
3738

3839
impl Folder for Shifter {
3940
fn fold_free_var(&mut self, depth: usize, binders: usize) -> Result<Ty> {

src/ir/debug.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -145,35 +145,28 @@ impl Debug for Normalize {
145145
}
146146
}
147147

148-
impl Debug for WhereClause {
148+
impl Debug for DomainGoal {
149149
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
150150
match *self {
151-
WhereClause::Normalize(ref n) => write!(fmt, "{:?}", n),
152-
WhereClause::Implemented(ref n) => {
151+
DomainGoal::Normalize(ref n) => write!(fmt, "{:?}", n),
152+
DomainGoal::RawNormalize(ref n) => write!(fmt, "raw {{ {:?} }}", n),
153+
DomainGoal::Implemented(ref n) => {
153154
write!(fmt,
154155
"{:?}: {:?}{:?}",
155156
n.parameters[0],
156157
n.trait_id,
157158
Angle(&n.parameters[1..]))
158159
}
160+
DomainGoal::WellFormed(ref n) => write!(fmt, "{:?}", n),
159161
}
160162
}
161163
}
162164

163-
impl Debug for WhereClauseGoal {
165+
impl Debug for LeafGoal {
164166
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
165167
match *self {
166-
WhereClauseGoal::Normalize(ref n) => write!(fmt, "{:?}", n),
167-
WhereClauseGoal::Implemented(ref n) => {
168-
write!(fmt,
169-
"{:?}: {:?}{:?}",
170-
n.parameters[0],
171-
n.trait_id,
172-
Angle(&n.parameters[1..]))
173-
}
174-
WhereClauseGoal::UnifyTys(ref n) => write!(fmt, "{:?}", n),
175-
WhereClauseGoal::UnifyLifetimes(ref n) => write!(fmt, "{:?}", n),
176-
WhereClauseGoal::WellFormed(ref n) => write!(fmt, "{:?}", n),
168+
LeafGoal::EqGoal(ref eq) => write!(fmt, "{:?}", eq),
169+
LeafGoal::DomainGoal(ref dom) => write!(fmt, "{:?}", dom),
177170
}
178171
}
179172
}
@@ -188,7 +181,7 @@ impl Debug for WellFormed {
188181
}
189182
}
190183

191-
impl<T: Debug> Debug for Unify<T> {
184+
impl Debug for EqGoal {
192185
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
193186
write!(fmt, "({:?} = {:?})", self.a, self.b)
194187
}
@@ -212,6 +205,7 @@ impl Debug for Goal {
212205
}
213206
Goal::Implies(ref wc, ref g) => write!(fmt, "if ({:?}) {{ {:?} }}", wc, g),
214207
Goal::And(ref g1, ref g2) => write!(fmt, "({:?}, {:?})", g1, g2),
208+
Goal::Not(ref g) => write!(fmt, "not {{ {:?} }}", g),
215209
Goal::Leaf(ref wc) => write!(fmt, "{:?}", wc),
216210
}
217211
}

0 commit comments

Comments
 (0)