Skip to content

Commit b18b1f5

Browse files
committed
limit to supertraits, first test working
1 parent 64057ba commit b18b1f5

File tree

5 files changed

+35
-66
lines changed

5 files changed

+35
-66
lines changed

crates/formality-prove/src/decls.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
use formality_macros::term;
22
use formality_types::{
3+
cast::Upcast,
34
collections::Set,
4-
grammar::{AliasName, AliasTy, Binder, TraitId, TraitRef, Ty, Wc, Wcs},
5+
grammar::{
6+
AliasName, AliasTy, Binder, Parameter, Predicate, Relation, TraitId, TraitRef, Ty, Wc, Wcs,
7+
PR,
8+
},
59
};
610

711
#[term]
@@ -90,8 +94,27 @@ impl TraitDecl {
9094
/// this would return the set `{trait_invariant(<ty Self> Ord(Self) => PartialOrd(Self)}`
9195
pub fn trait_invariants(&self) -> Set<TraitInvariant> {
9296
let (variables, TraitDeclBoundData { where_clause }) = self.binder.open();
97+
let self_var: Parameter = variables[0].upcast();
98+
99+
fn is_supertrait(self_var: &Parameter, wc: &Wc) -> bool {
100+
match wc.data() {
101+
formality_types::grammar::WcData::PR(PR::Predicate(Predicate::IsImplemented(
102+
trait_ref,
103+
))) => trait_ref.parameters[0] == *self_var,
104+
formality_types::grammar::WcData::PR(PR::Relation(Relation::Outlives(a, _))) => {
105+
*a == *self_var
106+
}
107+
formality_types::grammar::WcData::PR(_) => false,
108+
formality_types::grammar::WcData::ForAll(binder) => {
109+
is_supertrait(self_var, binder.peek())
110+
}
111+
formality_types::grammar::WcData::Implies(_, c) => is_supertrait(self_var, c),
112+
}
113+
}
114+
93115
where_clause
94116
.into_iter()
117+
.filter(|where_clause| is_supertrait(&self_var, where_clause))
95118
.map(|where_clause| TraitInvariant {
96119
binder: Binder::new(
97120
&variables,

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,14 @@ judgment_fn! {
7474
----------------------------- ("eq")
7575
(prove_wc(decls, env, assumptions, Relation::Equals(a, b)) => c)
7676
)
77+
78+
79+
(
80+
(let t = decls.trait_decl(&trait_ref.trait_id))
81+
(let t = t.binder.instantiate_with(&trait_ref.parameters).unwrap())
82+
(prove(decls, env, assumptions, t.where_clause) => c)
83+
----------------------------- ("trait well formed")
84+
(prove_wc(decls, env, assumptions, Predicate::WellFormedTraitRef(trait_ref)) => c)
85+
)
7786
}
7887
}

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

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ pub enum Predicate {
2222
#[cast]
2323
IsImplemented(TraitRef),
2424

25-
/// True if an alias normalizes to the given type.
26-
#[grammar(@NormalizesTo($v0 -> $v1))]
27-
NormalizesTo(AliasTy, Ty),
28-
29-
#[grammar(@WellFormedAdt($v0, $v1))]
30-
WellFormedAdt(AdtId, Parameters),
31-
32-
#[grammar(@WellFormedAlias($v0, $v1))]
33-
WellFormedAlias(AliasName, Parameters),
34-
3525
#[grammar(@WellFormedTraitRef($v0))]
3626
WellFormedTraitRef(TraitRef),
3727
}
@@ -53,32 +43,6 @@ impl std::ops::BitAnd for Coinductive {
5343
}
5444
}
5545

56-
impl Predicate {
57-
/// True if this goal can be proven via a cycle. For example,
58-
/// it is ok for a `T: Debug` impl to require `T: Debug`.
59-
pub fn is_coinductive(&self) -> Coinductive {
60-
match self {
61-
Predicate::IsImplemented(_) => Coinductive::Yes,
62-
Predicate::NormalizesTo(_, _) => Coinductive::No,
63-
Predicate::WellFormedAlias(_, _)
64-
| Predicate::WellFormedAdt(_, _)
65-
| Predicate::WellFormedTraitRef(_) => Coinductive::Yes,
66-
}
67-
}
68-
}
69-
70-
impl AliasName {
71-
pub fn well_formed(&self, t: impl Upcast<Vec<Parameter>>) -> Predicate {
72-
Predicate::WellFormedAlias(self.clone(), t.upcast())
73-
}
74-
}
75-
76-
impl AliasTy {
77-
pub fn normalizes_to(&self, t: impl Upcast<Ty>) -> Predicate {
78-
Predicate::NormalizesTo(self.clone(), t.upcast())
79-
}
80-
}
81-
8246
impl Ty {
8347
pub fn well_formed(&self) -> Relation {
8448
Relation::WellFormed(self.upcast())
@@ -102,10 +66,7 @@ impl Parameter {
10266
#[term]
10367
pub enum Skeleton {
10468
IsImplemented(TraitId),
105-
NormalizesTo(AliasName),
10669
WellFormed,
107-
WellFormedAdt(AdtId),
108-
WellFormedAlias(AliasName),
10970
WellFormedTraitRef(TraitId),
11071

11172
Equals,
@@ -125,20 +86,6 @@ impl Predicate {
12586
Skeleton::IsImplemented(trait_id.clone()),
12687
parameters.clone(),
12788
),
128-
Predicate::NormalizesTo(AliasTy { name, parameters }, ty) => (
129-
Skeleton::NormalizesTo(name.clone()),
130-
parameters
131-
.iter()
132-
.cloned()
133-
.chain(Some(ty.to_parameter()))
134-
.collect(),
135-
),
136-
Predicate::WellFormedAdt(id, parameters) => {
137-
(Skeleton::WellFormedAdt(id.clone()), parameters.clone())
138-
}
139-
Predicate::WellFormedAlias(id, parameters) => {
140-
(Skeleton::WellFormedAlias(id.clone()), parameters.clone())
141-
}
14289
Predicate::WellFormedTraitRef(TraitRef {
14390
trait_id,
14491
parameters,
@@ -160,12 +107,6 @@ impl TraitRef {
160107
}
161108
}
162109

163-
impl AdtId {
164-
pub fn well_formed(&self, parameters: impl Upcast<Vec<Parameter>>) -> Predicate {
165-
Predicate::WellFormedAdt(self.clone(), parameters.upcast())
166-
}
167-
}
168-
169110
/// Relations are built-in goals which are implemented in custom Rust logic.
170111
#[term]
171112
pub enum Relation {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
set,
1111
};
1212

13-
use super::{Binder, BoundVar, Predicate, Relation, TraitRef};
13+
use super::{Binder, BoundVar, Parameter, Predicate, Relation, TraitRef, Ty};
1414

1515
#[term($set)]
1616
pub struct Wcs {

tests/basic--hello_world.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![allow(non_snake_case)]
2-
#![cfg(FIXME)]
32

43
use formality::test_program_ok;
54

@@ -29,10 +28,7 @@ fn test_broken() {
2928
Err(
3029
Error {
3130
context: "check_trait(Foo)",
32-
source: Error {
33-
context: "prove_where_clause_well_formed([Bar(!tyU(1)_1, !tyU(1)_0)] => Bar(!tyU(1)_1, !tyU(1)_0)",
34-
source: "could not prove `well_formed_trait_ref(Bar(!tyU(1)_1, !tyU(1)_0))` given `[\n Bar(!tyU(1)_1, !tyU(1)_0),\n]`",
35-
},
31+
source: "failed to prove {@ WellFormedTraitRef(Bar(!ty_2, !ty_1))} given [!ty_2 : Bar < !ty_1 >], got {}",
3632
},
3733
)
3834
"#]].assert_debug_eq(&test_program_ok(PROGRAM_BROKEN));

0 commit comments

Comments
 (0)