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