@@ -246,65 +246,37 @@ where
246
246
|gb, impl_substitution, ( trait_ref, where_clauses) , associated_ty_value_ids| {
247
247
let interner = gb. interner ( ) ;
248
248
249
- // if (WC) { ... }
250
- gb. implies (
251
- where_clauses
249
+ // if (WC && input types are well formed) { ... }
250
+ let impl_wf = Self :: impl_wf_environment ( interner, & where_clauses, & trait_ref) ;
251
+ gb. implies ( impl_wf, |gb| {
252
+ let db = gb. db ( ) ;
253
+
254
+ let assoc_ty_goals = associated_ty_value_ids
252
255
. iter ( )
253
- . cloned ( )
254
- . map ( |qwc| qwc. into_from_env_goal ( interner) ) ,
255
- |gb| {
256
- // We retrieve all the input types of the type on which we implement the trait: we will
257
- // *assume* that these types are well-formed, e.g. we will be able to derive that
258
- // `K: Hash` holds without writing any where clause.
259
- //
260
- // Example:
261
- // ```
262
- // struct HashSet<K> where K: Hash { ... }
263
- //
264
- // impl<K> Foo for HashSet<K> {
265
- // // Inside here, we can rely on the fact that `K: Hash` holds
266
- // }
267
- // ```
268
- let mut header_input_types = Vec :: new ( ) ;
269
- trait_ref. fold ( interner, & mut header_input_types) ;
270
-
271
- gb. implies (
272
- header_input_types
273
- . into_iter ( )
274
- . map ( |ty| ty. into_from_env_goal ( interner) ) ,
275
- |gb| {
276
- let db = gb. db ( ) ;
277
-
278
- let assoc_ty_goals =
279
- associated_ty_value_ids. iter ( ) . filter_map ( |& id| {
280
- Self :: compute_assoc_ty_goal ( db, & impl_substitution, id)
281
- } ) ;
282
-
283
- // We retrieve all the input types of the where clauses appearing on the trait impl,
284
- // e.g. in:
285
- // ```
286
- // impl<T, K> Foo for (T, K) where T: Iterator<Item = (HashSet<K>, Vec<Box<T>>)> { ... }
287
- // ```
288
- // we would retrieve `HashSet<K>`, `Box<T>`, `Vec<Box<T>>`, `(HashSet<K>, Vec<Box<T>>)`.
289
- // We will have to prove that these types are well-formed (e.g. an additional `K: Hash`
290
- // bound would be needed here).
291
- let mut input_types = Vec :: new ( ) ;
292
- where_clauses. fold ( interner, & mut input_types) ;
293
-
294
- // Things to prove well-formed: input types of the where-clauses, projection types
295
- // appearing in the header, associated type values, and of course the trait ref.
296
- debug ! ( "verify_trait_impl: input_types={:?}" , input_types) ;
297
- let goals = input_types
298
- . into_iter ( )
299
- . map ( |ty| ty. well_formed ( ) . cast ( interner) )
300
- . chain ( assoc_ty_goals)
301
- . chain ( Some ( trait_ref. well_formed ( ) . cast ( interner) ) ) ;
302
-
303
- gb. all ( goals)
304
- } ,
305
- )
306
- } ,
307
- )
256
+ . filter_map ( |& id| Self :: compute_assoc_ty_goal ( db, & impl_substitution, id) ) ;
257
+
258
+ // We retrieve all the input types of the where clauses appearing on the trait impl,
259
+ // e.g. in:
260
+ // ```
261
+ // impl<T, K> Foo for (T, K) where T: Iterator<Item = (HashSet<K>, Vec<Box<T>>)> { ... }
262
+ // ```
263
+ // we would retrieve `HashSet<K>`, `Box<T>`, `Vec<Box<T>>`, `(HashSet<K>, Vec<Box<T>>)`.
264
+ // We will have to prove that these types are well-formed (e.g. an additional `K: Hash`
265
+ // bound would be needed here).
266
+ let mut input_types = Vec :: new ( ) ;
267
+ where_clauses. fold ( interner, & mut input_types) ;
268
+
269
+ // Things to prove well-formed: input types of the where-clauses, projection types
270
+ // appearing in the header, associated type values, and of course the trait ref.
271
+ debug ! ( "verify_trait_impl: input_types={:?}" , input_types) ;
272
+ let goals = input_types
273
+ . into_iter ( )
274
+ . map ( |ty| ty. well_formed ( ) . cast ( interner) )
275
+ . chain ( assoc_ty_goals)
276
+ . chain ( Some ( trait_ref. clone ( ) . well_formed ( ) . cast ( interner) ) ) ;
277
+
278
+ gb. all ( goals)
279
+ } )
308
280
} ,
309
281
) ;
310
282
@@ -327,6 +299,41 @@ where
327
299
}
328
300
}
329
301
302
+ /// Creates the conditions that an impl (and its contents of an impl)
303
+ /// can assume to be true when proving that it is well-formed.
304
+ fn impl_wf_environment < ' i > (
305
+ interner : & ' i I ,
306
+ where_clauses : & ' i [ QuantifiedWhereClause < I > ] ,
307
+ trait_ref : & ' i TraitRef < I > ,
308
+ ) -> impl Iterator < Item = ProgramClause < I > > + ' i {
309
+ // if (WC) { ... }
310
+ let wc = where_clauses
311
+ . iter ( )
312
+ . cloned ( )
313
+ . map ( move |qwc| qwc. into_from_env_goal ( interner) . cast ( interner) ) ;
314
+
315
+ // We retrieve all the input types of the type on which we implement the trait: we will
316
+ // *assume* that these types are well-formed, e.g. we will be able to derive that
317
+ // `K: Hash` holds without writing any where clause.
318
+ //
319
+ // Example:
320
+ // ```
321
+ // struct HashSet<K> where K: Hash { ... }
322
+ //
323
+ // impl<K> Foo for HashSet<K> {
324
+ // // Inside here, we can rely on the fact that `K: Hash` holds
325
+ // }
326
+ // ```
327
+ let mut header_input_types = Vec :: new ( ) ;
328
+ trait_ref. fold ( interner, & mut header_input_types) ;
329
+
330
+ let types_wf = header_input_types
331
+ . into_iter ( )
332
+ . map ( move |ty| ty. into_from_env_goal ( interner) . cast ( interner) ) ;
333
+
334
+ wc. chain ( types_wf)
335
+ }
336
+
330
337
/// Associated type values are special because they can be parametric (independently of
331
338
/// the impl), so we issue a special goal which is quantified using the binders of the
332
339
/// associated type value, for example in:
0 commit comments