@@ -5,6 +5,8 @@ use errors::*;
5
5
use cast:: * ;
6
6
use solve:: SolverChoice ;
7
7
use itertools:: Itertools ;
8
+ use fold:: * ;
9
+ use fold:: shift:: Shift ;
8
10
9
11
mod test;
10
12
@@ -207,38 +209,20 @@ impl WfSolver {
207
209
let mut input_types = Vec :: new ( ) ;
208
210
impl_datum. binders . value . where_clauses . fold ( & mut input_types) ;
209
211
210
- // We partition the input types of the type on which we implement the trait in two categories:
211
- // * projection types, e.g. `<T as Iterator>::Item`: we will have to prove that these types
212
- // are well-formed, e.g. that we can show that `T: Iterator` holds
213
- // * any other types, e.g. `HashSet<K>`: we will *assume* that these types are well-formed, e.g.
214
- // we will be able to derive that `K: Hash` holds without writing any where clause.
212
+ // We retrieve all the input types of the type on which we implement the trait: we will
213
+ // *assume* that these types are well-formed, e.g. we will be able to derive that
214
+ // `K: Hash` holds without writing any where clause.
215
215
//
216
- // Examples :
216
+ // Example :
217
217
// ```
218
218
// struct HashSet<K> where K: Hash { ... }
219
219
//
220
220
// impl<K> Foo for HashSet<K> {
221
221
// // Inside here, we can rely on the fact that `K: Hash` holds
222
222
// }
223
223
// ```
224
- //
225
- // ```
226
- // impl<T> Foo for <T as Iterator>::Item {
227
- // // The impl is not well-formed, as an exception we do not assume that
228
- // // `<T as Iterator>::Item` is well-formed and instead want to prove it.
229
- // }
230
- // ```
231
- //
232
- // ```
233
- // impl<T> Foo for <T as Iterator>::Item where T: Iterator {
234
- // // Now ok.
235
- // }
236
- // ```
237
224
let mut header_input_types = Vec :: new ( ) ;
238
225
trait_ref. fold ( & mut header_input_types) ;
239
- let ( header_projection_types, header_other_types) : ( Vec < _ > , Vec < _ > ) =
240
- header_input_types. into_iter ( )
241
- . partition ( |ty| ty. is_projection ( ) ) ;
242
226
243
227
// Associated type values are special because they can be parametric (independently of
244
228
// the impl), so we issue a special goal which is quantified using the binders of the
@@ -257,49 +241,48 @@ impl WfSolver {
257
241
let assoc_ty_datum = & self . env . associated_ty_data [ & assoc_ty. associated_ty_id ] ;
258
242
let bounds = & assoc_ty_datum. bounds ;
259
243
260
- let trait_datum = & self . env . trait_data [ & assoc_ty_datum. trait_id ] ;
261
-
262
244
let mut input_types = Vec :: new ( ) ;
263
245
assoc_ty. value . value . ty . fold ( & mut input_types) ;
264
246
265
- let goals = input_types. into_iter ( )
266
- . map ( |ty| DomainGoal :: WellFormedTy ( ty) . cast ( ) ) ;
267
- //.chain(bounds.iter()
268
- // .flat_map(|b| b.clone()
269
- // .lower_with_self(assoc_ty.value.value.ty.clone()))
270
- // .map(|g| g.into_well_formed_goal().cast()));
271
- let goal = goals. fold1 ( |goal, leaf| Goal :: And ( Box :: new ( goal) , Box :: new ( leaf) ) ) ;
272
- //.expect("at least one goal");
273
- let goal = goal //Goal::Implies(hypotheses, Box::new(goal))
274
- . map ( |goal| goal. quantify ( QuantifierKind :: ForAll , assoc_ty. value . binders . clone ( ) ) ) ; //binders);
275
-
276
- // FIXME this is wrong (and test)!
277
- let mut bound_binders = assoc_ty. value . binders . clone ( ) ;
278
- bound_binders. extend ( trait_datum. binders . binders . iter ( ) ) ;
247
+ let wf_goals =
248
+ input_types. into_iter ( )
249
+ . map ( |ty| DomainGoal :: WellFormedTy ( ty) ) ;
250
+
251
+ let trait_ref = trait_ref. up_shift ( assoc_ty. value . binders . len ( ) ) ;
252
+
253
+ let all_parameters: Vec < _ > =
254
+ assoc_ty. value . binders . iter ( )
255
+ . zip ( 0 ..)
256
+ . map ( |p| p. to_parameter ( ) )
257
+ . chain ( trait_ref. parameters . iter ( ) . cloned ( ) )
258
+ . collect ( ) ;
259
+
260
+ let bound_goals =
261
+ bounds. iter ( )
262
+ . map ( |b| Subst :: apply ( & all_parameters, b) )
263
+ . flat_map ( |b| b. lower_with_self ( assoc_ty. value . value . ty . clone ( ) ) )
264
+ . map ( |g| g. into_well_formed_goal ( ) ) ;
265
+
266
+ let goals = wf_goals. chain ( bound_goals) . casted ( ) ;
267
+ let goal = match goals. fold1 ( |goal, leaf| Goal :: And ( Box :: new ( goal) , Box :: new ( leaf) ) ) {
268
+ Some ( goal) => goal,
269
+ None => return None ,
270
+ } ;
279
271
280
272
let hypotheses =
281
273
assoc_ty_datum. where_clauses
282
274
. iter ( )
283
- . chain ( impl_datum. binders . value . where_clauses . iter ( ) ) // FIXME binders (and test)!
284
- . cloned ( )
275
+ . map ( |wc| Subst :: apply ( & all_parameters, wc) )
285
276
. map ( |wc| wc. map ( |bound| bound. into_from_env_goal ( ) ) )
286
277
. casted ( )
287
278
. collect ( ) ;
288
- let bound_goal = bounds. iter ( )
289
- . flat_map ( |b| b. clone ( )
290
- . lower_with_self ( assoc_ty. value . value . ty . clone ( ) ) )
291
- . map ( |g| g. into_well_formed_goal ( ) . cast ( ) )
292
- . fold1 ( |goal, leaf| Goal :: And ( Box :: new ( goal) , Box :: new ( leaf) ) ) ;
293
- let bound_goal = bound_goal. map ( |g| {
294
- Goal :: Implies ( hypotheses, Box :: new ( g) ) . quantify ( QuantifierKind :: ForAll , bound_binders)
295
- } ) ;
296
-
297
- let goal = goal. into_iter ( )
298
- . chain ( bound_goal. into_iter ( ) )
299
- . fold1 ( |goal, leaf| Goal :: And ( Box :: new ( goal) , Box :: new ( leaf) ) ) ;
300
- println ! ( "{:?}" , goal) ;
301
-
302
- goal
279
+
280
+ let goal = Goal :: Implies (
281
+ hypotheses,
282
+ Box :: new ( goal)
283
+ ) ;
284
+
285
+ Some ( goal. quantify ( QuantifierKind :: ForAll , assoc_ty. value . binders . clone ( ) ) )
303
286
} ;
304
287
305
288
let assoc_ty_goals =
@@ -316,7 +299,6 @@ impl WfSolver {
316
299
) ;
317
300
let goals =
318
301
input_types. into_iter ( )
319
- . chain ( header_projection_types. into_iter ( ) )
320
302
. map ( |ty| DomainGoal :: WellFormedTy ( ty) . cast ( ) )
321
303
. chain ( assoc_ty_goals)
322
304
. chain ( Some ( trait_ref_wf) . cast ( ) ) ;
@@ -335,12 +317,14 @@ impl WfSolver {
335
317
. cloned ( )
336
318
. map ( |wc| wc. map ( |bound| bound. into_from_env_goal ( ) ) )
337
319
. casted ( )
338
- . chain ( header_other_types . into_iter ( ) . map ( |ty| DomainGoal :: FromEnvTy ( ty) . cast ( ) ) )
320
+ . chain ( header_input_types . into_iter ( ) . map ( |ty| DomainGoal :: FromEnvTy ( ty) . cast ( ) ) )
339
321
. collect ( ) ;
340
322
341
323
let goal = Goal :: Implies ( hypotheses, Box :: new ( goal) )
342
324
. quantify ( QuantifierKind :: ForAll , impl_datum. binders . binders . clone ( ) ) ;
343
325
326
+ println ! ( "{:?}" , goal) ;
327
+
344
328
match self . solver_choice . solve_root_goal ( & self . env , & goal. into_closed_goal ( ) ) . unwrap ( ) {
345
329
Some ( sol) => sol. is_unique ( ) ,
346
330
None => false ,
0 commit comments