Skip to content

Commit fabaecb

Browse files
committed
check pos/neg impls are disjoint
1 parent 89f28d4 commit fabaecb

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

crates/formality-check/src/impls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ impl super::Check<'_> {
3535

3636
self.prove_goal(&env, &where_clauses, trait_ref.is_implemented())?;
3737

38+
self.prove_not_goal(&env, &where_clauses, trait_ref.not_implemented())?;
39+
3840
let trait_decl = self.program.trait_named(&trait_ref.trait_id)?;
3941
let TraitBoundData {
4042
where_clauses: _,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ impl std::ops::BitAnd for Coinductive {
4444
}
4545

4646
impl TraitRef {
47-
pub fn not_implemented(self) -> Predicate {
48-
Predicate::NotImplemented(self)
47+
pub fn not_implemented(&self) -> Predicate {
48+
Predicate::NotImplemented(self.clone())
4949
}
5050
}
5151

tests/coherence.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,46 @@ fn test_u32_T_where_T_Is_impls() {
9797
]",
9898
));
9999
}
100+
101+
#[test]
102+
fn test_u32_not_u32_impls() {
103+
expect_test::expect![[r#"
104+
Err(
105+
Error {
106+
context: "check_trait_impl(impl <> Foo < > for (rigid (scalar u32)) where [] { })",
107+
source: "failed to disprove {! Foo((rigid (scalar u32)))} given {}, got {Constraints { env: Env { variables: [] }, known_true: true, substitution: {} }}",
108+
},
109+
)
110+
"#]] // FIXME
111+
.assert_debug_eq(&test_program_ok(
112+
"[
113+
crate Foo {
114+
trait Foo<> where [] {}
115+
impl<> Foo<> for u32 where [] {}
116+
impl<> !Foo<> for u32 where [] {}
117+
}
118+
]",
119+
));
120+
}
121+
122+
#[test]
123+
#[allow(non_snake_case)]
124+
fn test_T_where_Foo_not_u32_impls() {
125+
expect_test::expect![[r#"
126+
Err(
127+
Error {
128+
context: "check_trait_impl(impl <ty> Foo < > for ^ty0_0 where [^ty0_0 : Foo < >] { })",
129+
source: "failed to disprove {! Foo(!ty_1)} given {Foo(!ty_1)}, got {Constraints { env: Env { variables: [?ty_1] }, known_true: true, substitution: {?ty_1 => (rigid (scalar u32))} }}",
130+
},
131+
)
132+
"#]] // FIXME
133+
.assert_debug_eq(&test_program_ok(
134+
"[
135+
crate Foo {
136+
trait Foo<> where [] {}
137+
impl<ty T> Foo<> for T where [T: Foo<>] {}
138+
impl<> !Foo<> for u32 where [] {}
139+
}
140+
]",
141+
));
142+
}

0 commit comments

Comments
 (0)