@@ -25,8 +25,9 @@ use llvm;
25
25
use monomorphize:: Instance ;
26
26
use rustc:: hir;
27
27
use rustc:: hir:: def_id:: DefId ;
28
+ use rustc:: traits;
28
29
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
29
- use rustc:: ty:: subst:: Substs ;
30
+ use rustc:: ty:: subst:: { Subst , Substs } ;
30
31
use syntax:: ast:: { self , NodeId } ;
31
32
use syntax:: attr;
32
33
use syntax_pos:: Span ;
@@ -250,6 +251,44 @@ impl<'a, 'tcx> TransItem<'tcx> {
250
251
}
251
252
}
252
253
254
+ /// Returns whether this instance is instantiable - whether it has no unsatisfied
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.
279
+ pub fn is_instantiable ( & self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> bool {
280
+ debug ! ( "is_instantiable({:?})" , self ) ;
281
+ let ( def_id, substs) = match * self {
282
+ TransItem :: Fn ( ref instance) => ( instance. def_id ( ) , instance. substs ) ,
283
+ TransItem :: Static ( node_id) => ( tcx. hir . local_def_id ( node_id) , Substs :: empty ( ) ) ,
284
+ // global asm never has predicates
285
+ TransItem :: GlobalAsm ( ..) => return true
286
+ } ;
287
+
288
+ let predicates = tcx. predicates_of ( def_id) . predicates . subst ( tcx, substs) ;
289
+ traits:: normalize_and_test_predicates ( tcx, predicates)
290
+ }
291
+
253
292
pub fn to_string ( & self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> String {
254
293
let hir_map = & tcx. hir ;
255
294
0 commit comments