@@ -7,7 +7,7 @@ use ir::*;
7
7
use cast:: * ;
8
8
use solve:: { SolverChoice , Solution } ;
9
9
10
- struct DisjointSolver {
10
+ struct OverlapSolver {
11
11
env : Arc < ProgramEnvironment > ,
12
12
solver_choice : SolverChoice ,
13
13
}
@@ -21,7 +21,7 @@ impl Program {
21
21
where
22
22
F : FnMut ( ItemId , ItemId ) ,
23
23
{
24
- let mut solver = DisjointSolver {
24
+ let mut solver = OverlapSolver {
25
25
env : Arc :: new ( self . environment ( ) ) ,
26
26
solver_choice,
27
27
} ;
@@ -65,7 +65,7 @@ impl Program {
65
65
// Check if the impls overlap, then if they do, check if one specializes
66
66
// the other. Note that specialization can only run one way - if both
67
67
// specialization checks return *either* true or false, that's an error.
68
- if ! solver. disjoint ( lhs, rhs) {
68
+ if solver. overlap ( lhs, rhs) {
69
69
match ( solver. specializes ( lhs, rhs) , solver. specializes ( rhs, lhs) ) {
70
70
( true , false ) => record_specialization ( l_id, r_id) ,
71
71
( false , true ) => record_specialization ( r_id, l_id) ,
@@ -82,36 +82,36 @@ impl Program {
82
82
}
83
83
}
84
84
85
- impl DisjointSolver {
86
- // Test if two impls are disjoint. If the test does not succeed, there is an overlap.
85
+ impl OverlapSolver {
86
+ // Test if the set of types that these two impls apply to overlap. If the test succeeds, these
87
+ // two impls overlap.
87
88
//
88
89
// We combine the binders of the two impls & treat them as existential
89
90
// quantifiers. Then we attempt to unify the input types to the trait provided
90
91
// by each impl, as well as prove that the where clauses from both impls all
91
- // hold. At the end, we negate the query because we only want to return `true` if
92
- // it is provable that there is no overlap.
92
+ // hold.
93
93
//
94
94
// Examples:
95
95
//
96
96
// Impls:
97
97
// impl<T> Foo for T { }
98
98
// impl Foo for i32 { }
99
99
// Generates:
100
- // compatible { not { exists<T> { T = i32 } } }
100
+ // compatible { exists<T> { T = i32 } }
101
101
//
102
102
// Impls:
103
103
// impl<T1, U> Foo<T1> for Vec<U> { }
104
104
// impl<T2> Foo<T2> for Vec<i32> { }
105
105
// Generates:
106
- // compatible { not { exists<T1, U, T2> { Vec<U> = Vec<i32>, T1 = T2 } } }
106
+ // compatible { exists<T1, U, T2> { Vec<U> = Vec<i32>, T1 = T2 } }
107
107
//
108
108
// Impls:
109
109
// impl<T> Foo for Vec<T> where T: Bar { }
110
110
// impl<U> Foo for Vec<U> where U: Baz { }
111
111
// Generates:
112
- // compatible { not { exists<T, U> { Vec<T> = Vec<U>, T: Bar, U: Baz } } }
112
+ // compatible { exists<T, U> { Vec<T> = Vec<U>, T: Bar, U: Baz } }
113
113
//
114
- fn disjoint ( & self , lhs : & ImplDatum , rhs : & ImplDatum ) -> bool {
114
+ fn overlap ( & self , lhs : & ImplDatum , rhs : & ImplDatum ) -> bool {
115
115
debug_heading ! ( "overlaps(lhs={:#?}, rhs={:#?})" , lhs, rhs) ;
116
116
117
117
let lhs_len = lhs. binders . len ( ) ;
@@ -150,19 +150,19 @@ impl DisjointSolver {
150
150
. fold1 ( |goal, leaf| Goal :: And ( Box :: new ( goal) , Box :: new ( leaf) ) )
151
151
. expect ( "Every trait takes at least one input type" )
152
152
. quantify ( QuantifierKind :: Exists , binders)
153
- . negate ( )
154
153
. compatible ( ) ;
155
154
156
155
let canonical_goal = & goal. into_closed_goal ( ) ;
157
156
let solution = self . solver_choice
158
157
. solve_root_goal ( & self . env , canonical_goal)
159
158
. unwrap ( ) ; // internal errors in the solver are fatal
160
159
let result = match solution {
161
- // Goal was proven with a unique solution, so impls are disjoint
162
- Some ( Solution :: Unique ( _) ) => true ,
160
+ // Goal was proven with a unique solution, so an impl was found that causes these two
161
+ // to overlap
162
+ Some ( Solution :: Unique ( _) ) |
163
163
// Goal was ambiguous, so there *may* be overlap
164
- Some ( Solution :: Ambig ( _) ) |
165
- // Goal cannot be proven, so impls definitely overlap
164
+ Some ( Solution :: Ambig ( _) ) => true ,
165
+ // Goal cannot be proven, so impls are disjoint
166
166
None => false ,
167
167
} ;
168
168
debug ! ( "overlaps: result = {:?}" , result) ;
0 commit comments