@@ -5,6 +5,8 @@ use errors::*;
55use cast:: * ;
66use solve:: SolverChoice ;
77use itertools:: Itertools ;
8+ use fold:: * ;
9+ use fold:: shift:: Shift ;
810
911mod test;
1012
@@ -207,38 +209,20 @@ impl WfSolver {
207209 let mut input_types = Vec :: new ( ) ;
208210 impl_datum. binders . value . where_clauses . fold ( & mut input_types) ;
209211
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.
215215 //
216- // Examples :
216+ // Example :
217217 // ```
218218 // struct HashSet<K> where K: Hash { ... }
219219 //
220220 // impl<K> Foo for HashSet<K> {
221221 // // Inside here, we can rely on the fact that `K: Hash` holds
222222 // }
223223 // ```
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- // ```
237224 let mut header_input_types = Vec :: new ( ) ;
238225 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 ( ) ) ;
242226
243227 // Associated type values are special because they can be parametric (independently of
244228 // the impl), so we issue a special goal which is quantified using the binders of the
@@ -257,49 +241,48 @@ impl WfSolver {
257241 let assoc_ty_datum = & self . env . associated_ty_data [ & assoc_ty. associated_ty_id ] ;
258242 let bounds = & assoc_ty_datum. bounds ;
259243
260- let trait_datum = & self . env . trait_data [ & assoc_ty_datum. trait_id ] ;
261-
262244 let mut input_types = Vec :: new ( ) ;
263245 assoc_ty. value . value . ty . fold ( & mut input_types) ;
264246
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+ } ;
279271
280272 let hypotheses =
281273 assoc_ty_datum. where_clauses
282274 . iter ( )
283- . chain ( impl_datum. binders . value . where_clauses . iter ( ) ) // FIXME binders (and test)!
284- . cloned ( )
275+ . map ( |wc| Subst :: apply ( & all_parameters, wc) )
285276 . map ( |wc| wc. map ( |bound| bound. into_from_env_goal ( ) ) )
286277 . casted ( )
287278 . 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 ( ) ) )
303286 } ;
304287
305288 let assoc_ty_goals =
@@ -316,7 +299,6 @@ impl WfSolver {
316299 ) ;
317300 let goals =
318301 input_types. into_iter ( )
319- . chain ( header_projection_types. into_iter ( ) )
320302 . map ( |ty| DomainGoal :: WellFormedTy ( ty) . cast ( ) )
321303 . chain ( assoc_ty_goals)
322304 . chain ( Some ( trait_ref_wf) . cast ( ) ) ;
@@ -335,12 +317,14 @@ impl WfSolver {
335317 . cloned ( )
336318 . map ( |wc| wc. map ( |bound| bound. into_from_env_goal ( ) ) )
337319 . 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 ( ) ) )
339321 . collect ( ) ;
340322
341323 let goal = Goal :: Implies ( hypotheses, Box :: new ( goal) )
342324 . quantify ( QuantifierKind :: ForAll , impl_datum. binders . binders . clone ( ) ) ;
343325
326+ println ! ( "{:?}" , goal) ;
327+
344328 match self . solver_choice . solve_root_goal ( & self . env , & goal. into_closed_goal ( ) ) . unwrap ( ) {
345329 Some ( sol) => sol. is_unique ( ) ,
346330 None => false ,
0 commit comments