Skip to content

Commit b953f83

Browse files
authored
Merge pull request #117 from scalexm/refactor
Refactor `lower` and reorganize tests
2 parents eeb2182 + a0b4928 commit b953f83

File tree

15 files changed

+1536
-1518
lines changed

15 files changed

+1536
-1518
lines changed

src/bin/chalki.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::sync::Arc;
1515
use std::process::exit;
1616

1717
use chalk::ir;
18-
use chalk::lower::*;
18+
use chalk::ir::lowering::*;
1919
use chalk::solve::SolverChoice;
2020
use docopt::Docopt;
2121
use rustyline::error::ReadlineError;

src/coherence/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use solve::SolverChoice;
66
use std::sync::Arc;
77

88
mod solve;
9-
9+
mod test;
1010

1111
impl Program {
1212
crate fn record_specialization_priorities(&mut self, solver_choice: SolverChoice) -> Result<()> {

src/coherence/test.rs

+228
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
#![cfg(test)]
2+
3+
use test_util::*;
4+
5+
#[test]
6+
fn two_impls_for_same_type() {
7+
lowering_error! {
8+
program {
9+
trait Foo { }
10+
struct Bar { }
11+
impl Foo for Bar { }
12+
impl Foo for Bar { }
13+
}
14+
error_msg {
15+
"overlapping impls of trait \"Foo\""
16+
}
17+
}
18+
}
19+
20+
#[test]
21+
fn generic_vec_and_specific_vec() {
22+
lowering_success! {
23+
program {
24+
trait Foo { }
25+
struct Vec<T> { }
26+
struct Bar { }
27+
impl Foo for Vec<Bar> { }
28+
impl<T> Foo for Vec<T> { }
29+
}
30+
}
31+
}
32+
33+
#[test]
34+
fn concrete_impl_and_blanket_impl() {
35+
lowering_success! {
36+
program {
37+
trait Foo { }
38+
struct Bar { }
39+
impl Foo for Bar { }
40+
impl<T> Foo for T { }
41+
}
42+
}
43+
}
44+
45+
#[test]
46+
fn two_blanket_impls() {
47+
lowering_error! {
48+
program {
49+
trait Foo { }
50+
trait Bar { }
51+
trait Baz { }
52+
impl<T> Foo for T where T: Bar { }
53+
impl<T> Foo for T where T: Baz { }
54+
struct Quux { }
55+
impl Bar for Quux { }
56+
impl Baz for Quux { }
57+
}
58+
error_msg {
59+
"overlapping impls of trait \"Foo\""
60+
}
61+
}
62+
}
63+
64+
#[test]
65+
// FIXME This should be an error
66+
// We currently assume a closed universe always, but overlaps checking should
67+
// assume an open universe - what if a client implemented both Bar and Baz
68+
//
69+
// In other words, this should have the same behavior as the two_blanket_impls
70+
// test.
71+
fn two_blanket_impls_open_ended() {
72+
lowering_success! {
73+
program {
74+
trait Foo { }
75+
trait Bar { }
76+
trait Baz { }
77+
impl<T> Foo for T where T: Bar { }
78+
impl<T> Foo for T where T: Baz { }
79+
}
80+
}
81+
}
82+
83+
#[test]
84+
fn multiple_nonoverlapping_impls() {
85+
lowering_success! {
86+
program {
87+
trait Foo { }
88+
struct Bar { }
89+
struct Baz<T> { }
90+
impl Foo for Bar { }
91+
impl<T> Foo for Baz<T> { }
92+
}
93+
}
94+
}
95+
96+
#[test]
97+
fn local_negative_reasoning_in_coherence() {
98+
lowering_success! {
99+
program {
100+
trait Foo { }
101+
trait Bar { }
102+
struct Baz { }
103+
impl<T> Foo for T where T: Bar { }
104+
impl Foo for Baz { }
105+
}
106+
}
107+
}
108+
109+
#[test]
110+
fn multiple_parameters() {
111+
lowering_error! {
112+
program {
113+
trait Foo<T> { }
114+
struct Baz { }
115+
116+
impl<T> Foo<Baz> for T { }
117+
impl<T> Foo<T> for Baz { }
118+
} error_msg {
119+
"overlapping impls of trait \"Foo\""
120+
}
121+
}
122+
}
123+
124+
#[test]
125+
fn nonoverlapping_assoc_types() {
126+
lowering_success! {
127+
program {
128+
trait Iterator {
129+
type Item;
130+
}
131+
struct Bar { }
132+
impl Iterator for Bar {
133+
type Item = Bar;
134+
}
135+
struct Baz<T> { }
136+
impl<T> Iterator for Baz<T> {
137+
type Item = Baz<T>;
138+
}
139+
140+
trait Foo { }
141+
impl Foo for <Bar as Iterator>::Item { }
142+
impl<T> Foo for <Baz<T> as Iterator>::Item { }
143+
}
144+
}
145+
}
146+
147+
#[test]
148+
fn overlapping_assoc_types() {
149+
lowering_success! {
150+
program {
151+
trait Foo<T> { }
152+
153+
trait Iterator { type Item; }
154+
155+
156+
struct Vec<T> { }
157+
impl<T> Iterator for Vec<T> { type Item = T; }
158+
159+
// This impl overlaps with the one below, but specializes it.
160+
impl<T> Foo<<T as Iterator>::Item> for T where T: Iterator { }
161+
162+
impl<A, B> Foo<A> for B { }
163+
}
164+
}
165+
}
166+
167+
#[test]
168+
fn overlapping_assoc_types_error() {
169+
lowering_error! {
170+
program {
171+
trait Foo<T> { }
172+
173+
trait Bar { }
174+
175+
trait Iterator { type Item; }
176+
177+
178+
struct Vec<T> { }
179+
impl<T> Iterator for Vec<T> { type Item = T; }
180+
181+
struct Other { }
182+
impl Bar for Other { }
183+
184+
// This impl overlaps with the one below, and does not
185+
// specialize because don't know that bar holds.
186+
impl<T> Foo<<T as Iterator>::Item> for T where T: Iterator { }
187+
188+
impl<A, B> Foo<A> for B where A: Bar { }
189+
} error_msg {
190+
"overlapping impls of trait \"Foo\""
191+
}
192+
}
193+
}
194+
195+
#[test]
196+
fn overlapping_negative_positive_impls() {
197+
lowering_error! {
198+
program {
199+
trait Send { }
200+
struct i32 { }
201+
202+
impl Send for i32 { }
203+
impl !Send for i32 { }
204+
} error_msg {
205+
"overlapping impls of trait \"Send\""
206+
}
207+
}
208+
}
209+
210+
#[test]
211+
fn overlapping_negative_impls() {
212+
lowering_success! {
213+
program {
214+
trait Send { }
215+
trait Foo { }
216+
trait Bar { }
217+
218+
struct Vec<T> { }
219+
struct i32 { }
220+
221+
impl Foo for i32 { }
222+
impl Bar for i32 { }
223+
224+
impl<T> !Send for Vec<T> where T: Foo { }
225+
impl<T> !Send for Vec<T> where T: Bar { }
226+
}
227+
}
228+
}

0 commit comments

Comments
 (0)