Skip to content

Commit 75ae1aa

Browse files
committed
add comments
1 parent 6e7e017 commit 75ae1aa

File tree

9 files changed

+62
-37
lines changed

9 files changed

+62
-37
lines changed

crates/formality-check/src/coherence.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,31 @@ impl Check<'_> {
4646
let a = env.instantiate_universally(&impl_a.binder);
4747
let trait_ref = a.trait_ref();
4848

49-
self.prove_goal(
50-
&env.with_coherence_mode(true),
51-
&a.where_clauses,
52-
trait_ref.is_local(),
53-
)
49+
self.prove_is_local_trait_ref(&env.with_coherence_mode(true), &a.where_clauses, trait_ref)
5450
}
5551

5652
#[tracing::instrument(level = "Debug", skip(self))]
5753
fn overlap_check(&self, impl_a: &TraitImpl, impl_b: &TraitImpl) -> Fallible<()> {
5854
let mut env = Env::default();
5955

56+
// Example:
57+
//
58+
// Given two impls...
59+
//
60+
// impl<P_a..> SomeTrait<T_a...> for T_a0 where Wc_a { }
61+
// impl<P_b..> SomeTrait<T_b...> for T_b0 where Wc_b { }
62+
63+
// ∀P_a, ∀P_b....
6064
let a = env.instantiate_universally(&impl_a.binder);
6165
let b = env.instantiate_universally(&impl_b.binder);
6266

67+
// ...get the trait refs from each impl...
6368
let trait_ref_a = a.trait_ref();
6469
let trait_ref_b = b.trait_ref();
6570

6671
// If the parameters from the two impls cannot be equal, then they do not overlap.
72+
//
73+
// If we can prove `∀P_a, ∀P_b. not (T_a = T_b, Wc_a, Wc_b)`, then they do not overlap.
6774
if let Ok(()) = self.prove_not_goal(
6875
&env.with_coherence_mode(true),
6976
(&a.where_clauses, &b.where_clauses),
@@ -73,6 +80,8 @@ impl Check<'_> {
7380
}
7481

7582
// If we can disprove the where clauses, then they do not overlap.
83+
//
84+
// If we can prove `∀P_a, ∀P_b. not [(T_a = T_b) => (Wc_a, Wc_b)]`, then they do not overlap.
7685
if let Ok(()) = self.prove_not_goal(
7786
&env.with_coherence_mode(true),
7887
Wcs::all_eq(&trait_ref_a.parameters, &trait_ref_b.parameters),
@@ -82,6 +91,11 @@ impl Check<'_> {
8291
}
8392

8493
// If we can disprove the where clauses, then they do not overlap.
94+
//
95+
// Given some inverted where-clause Wc_i from (invert(Wc_a), invert(Wc_b))...e.g.
96+
// if `T: Debug` is in `Wc_a`, then `Wc_i` might be `T: !Debug`.
97+
//
98+
// If we can prove `∀P_a, ∀P_b, (T_a = T_b, Wc_a, Wc_b) => Wc_i`, then contradiction, no overlap.
8599
let inverted: Vec<Wc> = a
86100
.where_clauses
87101
.iter()

crates/formality-check/src/lib.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ use formality_rust::{
88
grammar::{Crate, CrateItem, Program},
99
prove::ToWcs,
1010
};
11-
use formality_types::grammar::{Fallible, Substitution, Wcs};
11+
use formality_types::{
12+
cast::Upcast,
13+
grammar::{Fallible, Substitution, TraitRef, Wcs},
14+
};
1215

1316
/// Check all crates in the program. The crates must be in dependency order
1417
/// such that any prefix of the crates is a complete program.
@@ -98,7 +101,27 @@ impl Check<'_> {
98101
return Ok(());
99102
}
100103

101-
bail!("failed to prove {goal:?} given {assumptions:?}, got {cs:?}")
104+
bail!("failed to prove {goal:?} given {assumptions:?}; got {cs:?}")
105+
}
106+
107+
fn prove_is_local_trait_ref(
108+
&self,
109+
env: &Env,
110+
assumptions: impl ToWcs,
111+
goal: impl Upcast<TraitRef>,
112+
) -> Fallible<()> {
113+
let goal: TraitRef = goal.upcast();
114+
let assumptions: Wcs = assumptions.to_wcs();
115+
116+
assert!(env.only_universal_variables());
117+
assert!(env.encloses((&assumptions, &goal)));
118+
119+
let cs = formality_prove::prove_is_local_trait_ref(self.decls, env, &assumptions, &goal);
120+
if cs.iter().any(|c| c.unconditionally_true()) {
121+
return Ok(());
122+
}
123+
124+
bail!("failed to prove {goal:?} is local, given {assumptions:?}; got {cs:?}")
102125
}
103126

104127
fn prove_not_goal(&self, env: &Env, assumptions: impl ToWcs, goal: impl ToWcs) -> Fallible<()> {

crates/formality-prove/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod prove;
66

77
pub use decls::*;
88
pub use prove::prove;
9+
pub use prove::prove_is_local_trait_ref;
910
pub use prove::Env;
1011

1112
#[cfg(test)]

crates/formality-prove/src/prove.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod combinators;
12
mod constraints;
23
mod env;
34
mod is_local;
@@ -8,7 +9,6 @@ mod prove_normalize;
89
mod prove_via;
910
mod prove_wc;
1011
mod prove_wc_list;
11-
mod combinators;
1212

1313
pub use constraints::Constraints;
1414
use formality_types::{cast::Upcast, collections::Set, grammar::Wcs, set, visit::Visit};
@@ -19,6 +19,8 @@ use crate::decls::Decls;
1919
pub use self::env::Env;
2020
use self::prove_wc_list::prove_wc_list;
2121

22+
pub use is_local::prove_is_local_trait_ref;
23+
2224
/// Top-level entry point for proving things; other rules recurse to this one.
2325
pub fn prove(
2426
decls: impl Upcast<Decls>,

crates/formality-prove/src/prove/is_local.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use crate::{
4242
pub fn may_be_remote(decls: Decls, env: Env, assumptions: Wcs, goal: TraitRef) -> Set<Constraints> {
4343
assert!(env.is_in_coherence_mode());
4444

45-
let c = is_local_trait_ref(decls, &env, assumptions, goal);
45+
let c = prove_is_local_trait_ref(decls, &env, assumptions, goal);
4646

4747
if c.is_empty() {
4848
// Cannot possibly be local, so always remote.
@@ -59,7 +59,7 @@ pub fn may_be_remote(decls: Decls, env: Env, assumptions: Wcs, goal: TraitRef) -
5959
}
6060

6161
judgment_fn! {
62-
pub fn is_local_trait_ref(
62+
pub fn prove_is_local_trait_ref(
6363
decls: Decls,
6464
env: Env,
6565
assumptions: Wcs,
@@ -70,7 +70,7 @@ judgment_fn! {
7070
(
7171
(if decls.is_local_trait_id(&goal.trait_id))
7272
--- ("local trait")
73-
(is_local_trait_ref(decls, env, _assumptions, goal) => Constraints::none(env))
73+
(prove_is_local_trait_ref(decls, env, _assumptions, goal) => Constraints::none(env))
7474
)
7575

7676
(
@@ -80,7 +80,7 @@ judgment_fn! {
8080
(let goal = c1.substitution().apply(&goal))
8181
(for_all(&decls, &env, &assumptions, &goal.parameters[..i], &not_downstream) => c2)
8282
--- ("local parameter")
83-
(is_local_trait_ref(decls, env, assumptions, goal) => c1.seq(c2))
83+
(prove_is_local_trait_ref(decls, env, assumptions, goal) => c1.seq(c2))
8484
)
8585
}
8686
}

crates/formality-prove/src/prove/prove_wc.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ use formality_types::{
66
use crate::{
77
decls::Decls,
88
prove::{
9-
env::Env,
10-
is_local::{is_local_trait_ref, may_be_remote},
11-
prove,
12-
prove_after::prove_after,
13-
prove_eq::prove_eq,
9+
env::Env, is_local::may_be_remote, prove, prove_after::prove_after, prove_eq::prove_eq,
1410
prove_via::prove_via,
1511
},
1612
};
@@ -100,11 +96,5 @@ judgment_fn! {
10096
----------------------------- ("trait well formed")
10197
(prove_wc(decls, env, assumptions, Predicate::WellFormedTraitRef(trait_ref)) => c)
10298
)
103-
104-
(
105-
(is_local_trait_ref(decls, env, assumptions, trait_ref) => c)
106-
----------------------------- ("trait ref is local")
107-
(prove_wc(decls, env, assumptions, Predicate::IsLocal(trait_ref)) => c)
108-
)
10999
}
110100
}

crates/formality-prove/src/test.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ use std::sync::Arc;
33
use formality_macros::term;
44
use formality_types::{
55
collections::Set,
6-
grammar::{Binder, Wcs},
6+
grammar::{Binder, TraitRef, Wcs},
77
};
88

99
use crate::{
1010
decls::Decls,
1111
prove::{prove, Constraints, Env},
12+
prove_is_local_trait_ref,
1213
};
1314

1415
mod eq_assumptions;
@@ -31,6 +32,8 @@ enum TestAssertion {
3132
Exists(Binder<Arc<TestAssertion>>),
3233
#[grammar($v0 => $v1)]
3334
Prove(Wcs, Wcs),
35+
#[grammar($v0 => @IsLocal($v1))]
36+
IsLocal(Wcs, TraitRef),
3437
}
3538

3639
/// `t` represents some set of existential bindings combined with (assumptions, goals).
@@ -60,6 +63,10 @@ fn test_prove(decls: Decls, mut assertion: Arc<TestAssertion>) -> Set<Constraint
6063
return prove(decls, env, assumptions, goals);
6164
}
6265

66+
TestAssertion::IsLocal(assumptions, goal) => {
67+
return prove_is_local_trait_ref(decls, env, assumptions, goal);
68+
}
69+
6370
TestAssertion::CoherenceMode(assertion1) => {
6471
env = env.with_coherence_mode(true);
6572
assertion = assertion1.clone();

crates/formality-types/src/grammar/formulas.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ pub enum Predicate {
2424

2525
#[grammar(@WellFormedTraitRef($v0))]
2626
WellFormedTraitRef(TraitRef),
27-
28-
#[grammar(@IsLocal($v0))]
29-
IsLocal(TraitRef),
3027
}
3128

3229
/// A coinductive predicate is one that can be proven via a cycle.
@@ -78,7 +75,6 @@ pub enum Skeleton {
7875
NotImplemented(TraitId),
7976
WellFormed,
8077
WellFormedTraitRef(TraitId),
81-
IsLocal(TraitId),
8278

8379
Equals,
8480
Sub,
@@ -111,10 +107,6 @@ impl Predicate {
111107
Skeleton::WellFormedTraitRef(trait_id.clone()),
112108
parameters.clone(),
113109
),
114-
Predicate::IsLocal(TraitRef {
115-
trait_id,
116-
parameters,
117-
}) => (Skeleton::IsLocal(trait_id.clone()), parameters.clone()),
118110
}
119111
}
120112
}
@@ -127,10 +119,6 @@ impl TraitRef {
127119
pub fn well_formed(&self) -> Predicate {
128120
Predicate::WellFormedTraitRef(self.clone())
129121
}
130-
131-
pub fn is_local(&self) -> Predicate {
132-
Predicate::IsLocal(self.clone())
133-
}
134122
}
135123

136124
/// Relations are built-in goals which are implemented in custom Rust logic.

tests/coherence.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ fn test_orphan_basic() {
183183
Err(
184184
Error {
185185
context: "orphan_check(impl <> CoreTrait < > for (rigid (adt CoreStruct)) where [] { })",
186-
source: "failed to prove {@ IsLocal(CoreTrait((rigid (adt CoreStruct))))} given {}, got {}",
186+
source: "failed to prove CoreTrait((rigid (adt CoreStruct))) is local, given {}; got {}",
187187
},
188188
)
189189
"#]]

0 commit comments

Comments
 (0)