@@ -253,6 +253,29 @@ impl<'a, 'tcx> TransItem<'tcx> {
253
253
254
254
/// Returns whether this instance is instantiable - whether it has no unsatisfied
255
255
/// predicates.
256
+ ///
257
+ /// In order to translate an item, all of its predicates must hold, because
258
+ /// otherwise the item does not make sense. Type-checking ensures that
259
+ /// the predicates of every item that is *used by* a valid item *do*
260
+ /// hold, so we can rely on that.
261
+ ///
262
+ /// However, we translate collector roots (reachable items) and functions
263
+ /// in vtables when they are seen, even if they are not used, and so they
264
+ /// might not be instantiable. For example, a programmer can define this
265
+ /// public function:
266
+ ///
267
+ /// pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
268
+ /// <&mut () as Clone>::clone(&s);
269
+ /// }
270
+ ///
271
+ /// That function can't be translated, because the method `<&mut () as Clone>::clone`
272
+ /// does not exist. Luckily for us, that function can't ever be used,
273
+ /// because that would require for `&'a mut (): Clone` to hold, so we
274
+ /// can just not emit any code, or even a linker reference for it.
275
+ ///
276
+ /// Similarly, if a vtable method has such a signature, and therefore can't
277
+ /// be used, we can just not emit it and have a placeholder (a null pointer,
278
+ /// which will never be accessed) in its place.
256
279
pub fn is_instantiable ( & self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> bool {
257
280
debug ! ( "is_instantiable({:?})" , self ) ;
258
281
let ( def_id, substs) = match * self {
0 commit comments