add comments
This commit is contained in:
parent
3ac976861d
commit
a6ca302097
@ -304,7 +304,11 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||
scx.tcx().hir.krate().visit_all_item_likes(&mut visitor);
|
||||
}
|
||||
|
||||
// We can only translate items that are instantiable - items all of
|
||||
// whose predicates hold. Luckily, items that aren't instantiable
|
||||
// can't actually be used, so we can just skip translating them.
|
||||
roots.retain(|root| root.is_instantiable(scx.tcx()));
|
||||
|
||||
roots
|
||||
}
|
||||
|
||||
|
@ -253,6 +253,29 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
||||
|
||||
/// Returns whether this instance is instantiable - whether it has no unsatisfied
|
||||
/// predicates.
|
||||
///
|
||||
/// In order to translate an item, all of its predicates must hold, because
|
||||
/// otherwise the item does not make sense. Type-checking ensures that
|
||||
/// the predicates of every item that is *used by* a valid item *do*
|
||||
/// hold, so we can rely on that.
|
||||
///
|
||||
/// However, we translate collector roots (reachable items) and functions
|
||||
/// in vtables when they are seen, even if they are not used, and so they
|
||||
/// might not be instantiable. For example, a programmer can define this
|
||||
/// public function:
|
||||
///
|
||||
/// pub fn foo<'a>(s: &'a mut ()) where &'a mut (): Clone {
|
||||
/// <&mut () as Clone>::clone(&s);
|
||||
/// }
|
||||
///
|
||||
/// That function can't be translated, because the method `<&mut () as Clone>::clone`
|
||||
/// does not exist. Luckily for us, that function can't ever be used,
|
||||
/// because that would require for `&'a mut (): Clone` to hold, so we
|
||||
/// can just not emit any code, or even a linker reference for it.
|
||||
///
|
||||
/// Similarly, if a vtable method has such a signature, and therefore can't
|
||||
/// be used, we can just not emit it and have a placeholder (a null pointer,
|
||||
/// which will never be accessed) in its place.
|
||||
pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
|
||||
debug!("is_instantiable({:?})", self);
|
||||
let (def_id, substs) = match *self {
|
||||
|
Loading…
Reference in New Issue
Block a user