Skip to content

Commit d7d3f19

Browse files
committed
introduce ability to if we have typeck-tables for a given def-id
And use this in save-analysis, which used to read the map directly. This is an attempt to sidestep the failure occuring on homu that I cannot reproduce.
1 parent 2cca256 commit d7d3f19

File tree

4 files changed

+84
-53
lines changed

4 files changed

+84
-53
lines changed

src/librustc/ty/maps.rs

+2
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,8 @@ define_maps! { <'tcx>
537537

538538
[] typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
539539

540+
[] has_typeck_tables: TypeckTables(DefId) -> bool,
541+
540542
[] coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
541543

542544
[] borrowck: BorrowCheck(DefId) -> (),

src/librustc_save_analysis/dump_visitor.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,15 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
114114
where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>)
115115
{
116116
let item_def_id = self.tcx.hir.local_def_id(item_id);
117-
let tables = self.tcx.typeck_tables_of(item_def_id);
118-
let old_tables = self.save_ctxt.tables;
119-
self.save_ctxt.tables = tables;
120-
f(self);
121-
self.save_ctxt.tables = old_tables;
117+
if self.tcx.has_typeck_tables(item_def_id) {
118+
let tables = self.tcx.typeck_tables_of(item_def_id);
119+
let old_tables = self.save_ctxt.tables;
120+
self.save_ctxt.tables = tables;
121+
f(self);
122+
self.save_ctxt.tables = old_tables;
123+
} else {
124+
f(self)
125+
}
122126
}
123127

124128
pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {

src/librustc_typeck/check/mod.rs

+72-45
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ pub fn provide(providers: &mut Providers) {
637637
*providers = Providers {
638638
typeck_item_bodies,
639639
typeck_tables_of,
640+
has_typeck_tables,
640641
closure_type,
641642
closure_kind,
642643
adt_destructor,
@@ -664,55 +665,49 @@ fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
664665
tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
665666
}
666667

667-
fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
668-
def_id: DefId)
669-
-> &'tcx ty::TypeckTables<'tcx> {
670-
// Closures' tables come from their outermost function,
671-
// as they are part of the same "inference environment".
672-
let outer_def_id = tcx.closure_base_def_id(def_id);
673-
if outer_def_id != def_id {
674-
return tcx.typeck_tables_of(outer_def_id);
675-
}
676-
677-
let id = tcx.hir.as_local_node_id(def_id).unwrap();
678-
let span = tcx.hir.span(id);
679-
let unsupported = || {
680-
span_bug!(span, "can't type-check body of {:?}", def_id);
681-
};
682-
683-
// Figure out what primary body this item has.
684-
let mut fn_decl = None;
685-
let body_id = match tcx.hir.get(id) {
668+
/// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
669+
/// with information about it's body-id and fn-decl (if any). Otherwise,
670+
/// returns `None`.
671+
///
672+
/// If this function returns "some", then `typeck_tables(def_id)` will
673+
/// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
674+
/// may not succeed. In some cases where this function returns `None`
675+
/// (notably closures), `typeck_tables(def_id)` would wind up
676+
/// redirecting to the owning function.
677+
fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
678+
id: ast::NodeId)
679+
-> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
680+
{
681+
match tcx.hir.get(id) {
686682
hir::map::NodeItem(item) => {
687683
match item.node {
688684
hir::ItemConst(_, body) |
689-
hir::ItemStatic(_, _, body) => body,
690-
hir::ItemFn(ref decl, .., body) => {
691-
fn_decl = Some(decl);
692-
body
693-
}
694-
_ => unsupported()
685+
hir::ItemStatic(_, _, body) =>
686+
Some((body, None)),
687+
hir::ItemFn(ref decl, .., body) =>
688+
Some((body, Some(decl))),
689+
_ =>
690+
None,
695691
}
696692
}
697693
hir::map::NodeTraitItem(item) => {
698694
match item.node {
699-
hir::TraitItemKind::Const(_, Some(body)) => body,
700-
hir::TraitItemKind::Method(ref sig,
701-
hir::TraitMethod::Provided(body)) => {
702-
fn_decl = Some(&sig.decl);
703-
body
704-
}
705-
_ => unsupported()
695+
hir::TraitItemKind::Const(_, Some(body)) =>
696+
Some((body, None)),
697+
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
698+
Some((body, Some(&sig.decl))),
699+
_ =>
700+
None,
706701
}
707702
}
708703
hir::map::NodeImplItem(item) => {
709704
match item.node {
710-
hir::ImplItemKind::Const(_, body) => body,
711-
hir::ImplItemKind::Method(ref sig, body) => {
712-
fn_decl = Some(&sig.decl);
713-
body
714-
}
715-
_ => unsupported()
705+
hir::ImplItemKind::Const(_, body) =>
706+
Some((body, None)),
707+
hir::ImplItemKind::Method(ref sig, body) =>
708+
Some((body, Some(&sig.decl))),
709+
_ =>
710+
None,
716711
}
717712
}
718713
hir::map::NodeExpr(expr) => {
@@ -723,15 +718,47 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
723718
// Assume that everything other than closures
724719
// is a constant "initializer" expression.
725720
match expr.node {
726-
hir::ExprClosure(..) => {
727-
// We should've bailed out above for closures.
728-
span_bug!(expr.span, "unexpected closure")
729-
}
730-
_ => hir::BodyId { node_id: expr.id }
721+
hir::ExprClosure(..) =>
722+
None,
723+
_ =>
724+
Some((hir::BodyId { node_id: expr.id }, None)),
731725
}
732726
}
733-
_ => unsupported()
734-
};
727+
_ => None,
728+
}
729+
}
730+
731+
fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
732+
def_id: DefId)
733+
-> bool {
734+
// Closures' tables come from their outermost function,
735+
// as they are part of the same "inference environment".
736+
let outer_def_id = tcx.closure_base_def_id(def_id);
737+
if outer_def_id != def_id {
738+
return tcx.has_typeck_tables(outer_def_id);
739+
}
740+
741+
let id = tcx.hir.as_local_node_id(def_id).unwrap();
742+
primary_body_of(tcx, id).is_some()
743+
}
744+
745+
fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
746+
def_id: DefId)
747+
-> &'tcx ty::TypeckTables<'tcx> {
748+
// Closures' tables come from their outermost function,
749+
// as they are part of the same "inference environment".
750+
let outer_def_id = tcx.closure_base_def_id(def_id);
751+
if outer_def_id != def_id {
752+
return tcx.typeck_tables_of(outer_def_id);
753+
}
754+
755+
let id = tcx.hir.as_local_node_id(def_id).unwrap();
756+
let span = tcx.hir.span(id);
757+
758+
// Figure out what primary body this item has.
759+
let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
760+
span_bug!(span, "can't type-check body of {:?}", def_id);
761+
});
735762
let body = tcx.hir.body(body_id);
736763

737764
Inherited::build(tcx, id).enter(|inh| {

src/librustc_typeck/check_unused.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
6363
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
6464
let mut used_trait_imports = DefIdSet();
6565
for &body_id in tcx.hir.krate().bodies.keys() {
66-
let item_id = tcx.hir.body_owner(body_id);
67-
let item_def_id = tcx.hir.local_def_id(item_id);
68-
66+
let item_def_id = tcx.hir.body_owner_def_id(body_id);
6967
let tables = tcx.typeck_tables_of(item_def_id);
7068
let imports = &tables.used_trait_imports;
7169
debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);

0 commit comments

Comments
 (0)