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);
|
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.retain(|root| root.is_instantiable(scx.tcx()));
|
||||||
|
|
||||||
roots
|
roots
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +253,29 @@ impl<'a, 'tcx> TransItem<'tcx> {
|
|||||||
|
|
||||||
/// Returns whether this instance is instantiable - whether it has no unsatisfied
|
/// Returns whether this instance is instantiable - whether it has no unsatisfied
|
||||||
/// predicates.
|
/// 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 {
|
pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
|
||||||
debug!("is_instantiable({:?})", self);
|
debug!("is_instantiable({:?})", self);
|
||||||
let (def_id, substs) = match *self {
|
let (def_id, substs) = match *self {
|
||||||
|
Loading…
Reference in New Issue
Block a user