Skip to content

Commit b33240e

Browse files
trans::collector: Also consider initializers of const items.
1 parent ab80f74 commit b33240e

File tree

1 file changed

+45
-16
lines changed

1 file changed

+45
-16
lines changed

src/librustc_trans/collector.rs

+45-16
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ use rustc::mir::visit::Visitor as MirVisitor;
205205
use syntax::abi::Abi;
206206
use errors;
207207
use syntax_pos::DUMMY_SP;
208+
use syntax::ast::NodeId;
208209
use base::custom_coerce_unsize_info;
209210
use context::SharedCrateContext;
210211
use common::{fulfill_obligation, normalize_and_test_predicates, type_is_sized};
@@ -349,17 +350,14 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
349350
|| format!("Could not find MIR for static: {:?}", def_id));
350351

351352
let empty_substs = scx.empty_substs_for_def_id(def_id);
352-
let mut visitor = MirNeighborCollector {
353+
let visitor = MirNeighborCollector {
353354
scx: scx,
354355
mir: &mir,
355356
output: &mut neighbors,
356357
param_substs: empty_substs
357358
};
358359

359-
visitor.visit_mir(&mir);
360-
for promoted in &mir.promoted {
361-
visitor.visit_mir(promoted);
362-
}
360+
visit_mir_and_promoted(visitor, &mir);
363361
}
364362
TransItem::Fn(instance) => {
365363
// Keep track of the monomorphization recursion depth
@@ -372,17 +370,14 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
372370
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def),
373371
|| format!("Could not find MIR for function: {}", instance));
374372

375-
let mut visitor = MirNeighborCollector {
373+
let visitor = MirNeighborCollector {
376374
scx: scx,
377375
mir: &mir,
378376
output: &mut neighbors,
379377
param_substs: instance.substs
380378
};
381379

382-
visitor.visit_mir(&mir);
383-
for promoted in &mir.promoted {
384-
visitor.visit_mir(promoted);
385-
}
380+
visit_mir_and_promoted(visitor, &mir);
386381
}
387382
}
388383

@@ -467,17 +462,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
467462
&substs.func_substs);
468463
let concrete_substs = self.scx.tcx().erase_regions(&concrete_substs);
469464

470-
let mut visitor = MirNeighborCollector {
465+
let visitor = MirNeighborCollector {
471466
scx: self.scx,
472467
mir: &mir,
473468
output: self.output,
474469
param_substs: concrete_substs
475470
};
476471

477-
visitor.visit_mir(&mir);
478-
for promoted in &mir.promoted {
479-
visitor.visit_mir(promoted);
480-
}
472+
visit_mir_and_promoted(visitor, &mir);
481473
}
482474
// When doing an cast from a regular pointer to a fat pointer, we
483475
// have to instantiate all methods of the trait being cast to, so we
@@ -1087,7 +1079,6 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
10871079
hir::ItemTy(..) |
10881080
hir::ItemDefaultImpl(..) |
10891081
hir::ItemTrait(..) |
1090-
hir::ItemConst(..) |
10911082
hir::ItemMod(..) => {
10921083
// Nothing to do, just keep recursing...
10931084
}
@@ -1124,6 +1115,12 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
11241115
self.scx.tcx().map.local_def_id(item.id)));
11251116
self.output.push(TransItem::Static(item.id));
11261117
}
1118+
hir::ItemConst(..) => {
1119+
debug!("RootCollector: ItemConst({})",
1120+
def_id_to_string(self.scx.tcx(),
1121+
self.scx.tcx().map.local_def_id(item.id)));
1122+
add_roots_for_const_item(self.scx, item.id, self.output);
1123+
}
11271124
hir::ItemFn(_, _, _, _, ref generics, _) => {
11281125
if !generics.is_type_parameterized() {
11291126
let def_id = self.scx.tcx().map.local_def_id(item.id);
@@ -1243,6 +1240,38 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12431240
}
12441241
}
12451242

1243+
// There are no translation items for constants themselves but their
1244+
// initializers might still contain something that produces translation items,
1245+
// such as cast that introduce a new vtable.
1246+
fn add_roots_for_const_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
1247+
const_item_node_id: NodeId,
1248+
output: &mut Vec<TransItem<'tcx>>)
1249+
{
1250+
let def_id = scx.tcx().map.local_def_id(const_item_node_id);
1251+
1252+
// Scan the MIR in order to find function calls, closures, and
1253+
// drop-glue
1254+
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
1255+
|| format!("Could not find MIR for const: {:?}", def_id));
1256+
1257+
let empty_substs = scx.empty_substs_for_def_id(def_id);
1258+
let visitor = MirNeighborCollector {
1259+
scx: scx,
1260+
mir: &mir,
1261+
output: output,
1262+
param_substs: empty_substs
1263+
};
1264+
1265+
visit_mir_and_promoted(visitor, &mir);
1266+
}
1267+
1268+
fn visit_mir_and_promoted<'tcx, V: MirVisitor<'tcx>>(mut visitor: V, mir: &mir::Mir<'tcx>) {
1269+
visitor.visit_mir(&mir);
1270+
for promoted in &mir.promoted {
1271+
visitor.visit_mir(promoted);
1272+
}
1273+
}
1274+
12461275
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12471276
pub enum TransItemState {
12481277
PredictedAndGenerated,

0 commit comments

Comments
 (0)