Skip to content

Commit 9a3f6c6

Browse files
committed
add negative trait impls
1 parent e8766aa commit 9a3f6c6

File tree

13 files changed

+125
-32
lines changed

13 files changed

+125
-32
lines changed

crates/formality-check/src/impls.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use fn_error_context::context;
44
use formality_prove::Env;
55
use formality_rust::grammar::{
66
AssociatedTy, AssociatedTyBoundData, AssociatedTyValue, AssociatedTyValueBoundData, Fn,
7-
FnBoundData, ImplItem, TraitBoundData, TraitImpl, TraitImplBoundData, TraitItem, WhereClause,
7+
FnBoundData, ImplItem, NegTraitImpl, NegTraitImplBoundData, TraitBoundData, TraitImpl,
8+
TraitImplBoundData, TraitItem, WhereClause,
89
};
910
use formality_types::{
1011
cast::Downcasted,
@@ -47,6 +48,25 @@ impl super::Check<'_> {
4748
Ok(())
4849
}
4950

51+
pub(super) fn check_neg_trait_impl(&self, i: &NegTraitImpl) -> Fallible<()> {
52+
let mut env = Env::default();
53+
54+
let NegTraitImplBoundData {
55+
trait_id,
56+
self_ty,
57+
trait_parameters,
58+
where_clauses,
59+
} = env.instantiate_universally(&i.binder);
60+
61+
let trait_ref = trait_id.with(self_ty, trait_parameters);
62+
63+
self.prove_where_clauses_well_formed(&env, &where_clauses, &where_clauses)?;
64+
65+
self.prove_goal(&env, &where_clauses, trait_ref.not_implemented())?;
66+
67+
Ok(())
68+
}
69+
5070
#[requires(assumptions.iter().all(|a| a.references_only_placeholder_variables()))]
5171
fn check_trait_impl_item(
5272
&self,

crates/formality-check/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl Check<'_> {
8585
CrateItem::Struct(s) => self.check_adt(&s.to_adt()),
8686
CrateItem::Enum(e) => self.check_adt(&e.to_adt()),
8787
CrateItem::Fn(f) => self.check_free_fn(f),
88+
CrateItem::NegTraitImpl(i) => self.check_neg_trait_impl(i),
8889
}
8990
}
9091

crates/formality-prove/src/decls.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub struct Decls {
1313
pub max_size: usize,
1414
pub trait_decls: Vec<TraitDecl>,
1515
pub impl_decls: Vec<ImplDecl>,
16+
pub neg_impl_decls: Vec<NegImplDecl>,
1617
pub alias_eq_decls: Vec<AliasEqDecl>,
1718
pub alias_bound_decls: Vec<AliasBoundDecl>,
1819
}
@@ -27,6 +28,15 @@ impl Decls {
2728
.filter(move |i| i.binder.peek().trait_ref.trait_id == *trait_id)
2829
}
2930

31+
pub fn neg_impl_decls<'s>(
32+
&'s self,
33+
trait_id: &'s TraitId,
34+
) -> impl Iterator<Item = &'s NegImplDecl> {
35+
self.neg_impl_decls
36+
.iter()
37+
.filter(move |i| i.binder.peek().trait_ref.trait_id == *trait_id)
38+
}
39+
3040
pub fn trait_decl(&self, trait_id: &TraitId) -> &TraitDecl {
3141
let mut v: Vec<_> = self
3242
.trait_decls
@@ -65,6 +75,7 @@ impl Decls {
6575
max_size: Decls::DEFAULT_MAX_SIZE,
6676
trait_decls: vec![],
6777
impl_decls: vec![],
78+
neg_impl_decls: vec![],
6879
alias_eq_decls: vec![],
6980
alias_bound_decls: vec![],
7081
}
@@ -82,6 +93,17 @@ pub struct ImplDeclBoundData {
8293
pub where_clause: Wcs,
8394
}
8495

96+
#[term(impl $binder)]
97+
pub struct NegImplDecl {
98+
pub binder: Binder<NegImplDeclBoundData>,
99+
}
100+
101+
#[term(!$trait_ref where $where_clause)]
102+
pub struct NegImplDeclBoundData {
103+
pub trait_ref: TraitRef,
104+
pub where_clause: Wcs,
105+
}
106+
85107
#[term(trait $id $binder)]
86108
pub struct TraitDecl {
87109
pub id: TraitId,

crates/formality-prove/src/test/eq_partial_eq.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@ use crate::{decls::Decls, prove::prove};
1010
/// Simple example decls consisting only of two trait declarations.
1111
fn decls() -> Decls {
1212
Decls {
13-
max_size: Decls::DEFAULT_MAX_SIZE,
1413
trait_decls: vec![
1514
term("trait Eq<ty Self> where {PartialEq(Self)}"),
1615
term("trait PartialEq<ty Self> where {}"),
1716
],
18-
impl_decls: vec![],
19-
alias_eq_decls: vec![],
20-
alias_bound_decls: vec![],
17+
..Decls::empty()
2118
}
2219
}
2320

crates/formality-prove/src/test/exists_constraints.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ use super::test_prove;
99
/// Simple example decls consisting only of two trait declarations.
1010
fn decls() -> Decls {
1111
Decls {
12-
max_size: Decls::DEFAULT_MAX_SIZE,
1312
trait_decls: vec![term("trait Foo<ty Self> where {}")],
1413
impl_decls: vec![term("impl<ty T> Foo(Vec<T>) where {}")],
15-
alias_eq_decls: vec![],
16-
alias_bound_decls: vec![],
14+
..Decls::empty()
1715
}
1816
}
1917

crates/formality-prove/src/test/expanding.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ fn decls() -> Decls {
1010
max_size: 10,
1111
trait_decls: vec![term("trait Debug<ty Self> where {}")],
1212
impl_decls: vec![term("impl<ty T> Debug(Vec<T>) where {Debug(T)}")],
13-
alias_eq_decls: vec![],
14-
alias_bound_decls: vec![],
13+
..Decls::empty()
1514
}
1615
}
1716

crates/formality-prove/src/test/magic_copy.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use super::test_prove;
99
/// Simple example decls consisting only of two trait declarations.
1010
fn decls() -> Decls {
1111
Decls {
12-
max_size: Decls::DEFAULT_MAX_SIZE,
1312
trait_decls: vec![
1413
term("trait Copy<ty Self> where {}"),
1514
term("trait Magic<ty Self> where {Copy(Self)}"),
@@ -18,8 +17,7 @@ fn decls() -> Decls {
1817
term("impl<ty T> Magic(T) where {Magic(T)}"),
1918
term("impl<> Copy(u32) where {}"),
2019
],
21-
alias_eq_decls: vec![],
22-
alias_bound_decls: vec![],
20+
..Decls::empty()
2321
}
2422
}
2523

crates/formality-prove/src/test/occurs_check.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ use super::test_prove;
99
/// Simple example decls consisting only of two trait declarations.
1010
fn decls() -> Decls {
1111
Decls {
12-
max_size: Decls::DEFAULT_MAX_SIZE,
1312
trait_decls: vec![term("trait Foo<ty Self> where {}")],
1413
impl_decls: vec![term("impl<ty T> Foo(Vec<T>) where {}")],
15-
alias_eq_decls: vec![],
16-
alias_bound_decls: vec![],
14+
..Decls::empty()
1715
}
1816
}
1917

crates/formality-prove/src/test/simple_impl.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ use crate::{decls::Decls, prove::prove};
77
/// Simple example decls consisting only of two trait declarations.
88
fn decls() -> Decls {
99
Decls {
10-
max_size: Decls::DEFAULT_MAX_SIZE,
1110
trait_decls: vec![term("trait Debug<ty Self> where {}")],
1211
impl_decls: vec![
1312
term("impl<ty T> Debug(Vec<T>) where {Debug(T)}"),
1413
term("impl<> Debug(u32) where {}"),
1514
],
16-
alias_eq_decls: vec![],
17-
alias_bound_decls: vec![],
15+
..Decls::empty()
1816
}
1917
}
2018

crates/formality-prove/src/test/universes.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ fn exists_u_for_t() {
1919
#[test]
2020
fn for_t_exists_u() {
2121
let decls = Decls {
22-
max_size: Decls::DEFAULT_MAX_SIZE,
2322
trait_decls: vec![term("trait Test<ty Self, ty T> where {}")],
2423
impl_decls: vec![term("impl<ty X, ty Y> Test(X, Y) where {X = Y}")],
25-
alias_eq_decls: vec![],
26-
alias_bound_decls: vec![],
24+
..Decls::empty()
2725
};
2826

2927
let constraints = super::test_prove(decls, term("{} => {for<ty T> Test(T, T)}"));

0 commit comments

Comments
 (0)