Skip to content

Commit a6ca302

Browse files
committed
add comments
1 parent 3ac9768 commit a6ca302

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

src/librustc_trans/collector.rs

+4
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,11 @@ fn collect_roots<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
304304
scx.tcx().hir.krate().visit_all_item_likes(&mut visitor);
305305
}
306306

307+
// We can only translate items that are instantiable - items all of
308+
// whose predicates hold. Luckily, items that aren't instantiable
309+
// can't actually be used, so we can just skip translating them.
307310
roots.retain(|root| root.is_instantiable(scx.tcx()));
311+
308312
roots
309313
}
310314

src/librustc_trans/trans_item.rs

+23
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,29 @@ impl<'a, 'tcx> TransItem<'tcx> {
253253

254254
/// Returns whether this instance is instantiable - whether it has no unsatisfied
255255
/// 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.
256279
pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
257280
debug!("is_instantiable({:?})", self);
258281
let (def_id, substs) = match *self {

0 commit comments

Comments
 (0)