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.
This commit is contained in:
parent
2cca2567d9
commit
d7d3f197f6
|
@ -537,6 +537,8 @@ define_maps! { <'tcx>
|
||||||
|
|
||||||
[] typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
|
[] typeck_tables_of: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>,
|
||||||
|
|
||||||
|
[] has_typeck_tables: TypeckTables(DefId) -> bool,
|
||||||
|
|
||||||
[] coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
|
[] coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
|
||||||
|
|
||||||
[] borrowck: BorrowCheck(DefId) -> (),
|
[] borrowck: BorrowCheck(DefId) -> (),
|
||||||
|
|
|
@ -114,11 +114,15 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>)
|
where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>)
|
||||||
{
|
{
|
||||||
let item_def_id = self.tcx.hir.local_def_id(item_id);
|
let item_def_id = self.tcx.hir.local_def_id(item_id);
|
||||||
let tables = self.tcx.typeck_tables_of(item_def_id);
|
if self.tcx.has_typeck_tables(item_def_id) {
|
||||||
let old_tables = self.save_ctxt.tables;
|
let tables = self.tcx.typeck_tables_of(item_def_id);
|
||||||
self.save_ctxt.tables = tables;
|
let old_tables = self.save_ctxt.tables;
|
||||||
f(self);
|
self.save_ctxt.tables = tables;
|
||||||
self.save_ctxt.tables = old_tables;
|
f(self);
|
||||||
|
self.save_ctxt.tables = old_tables;
|
||||||
|
} else {
|
||||||
|
f(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
|
pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
|
||||||
|
|
|
@ -637,6 +637,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
typeck_item_bodies,
|
typeck_item_bodies,
|
||||||
typeck_tables_of,
|
typeck_tables_of,
|
||||||
|
has_typeck_tables,
|
||||||
closure_type,
|
closure_type,
|
||||||
closure_kind,
|
closure_kind,
|
||||||
adt_destructor,
|
adt_destructor,
|
||||||
|
@ -664,55 +665,49 @@ fn adt_destructor<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
|
tcx.calculate_dtor(def_id, &mut dropck::check_drop_impl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
/// If this def-id is a "primary tables entry", returns `Some((body_id, decl))`
|
||||||
def_id: DefId)
|
/// with information about it's body-id and fn-decl (if any). Otherwise,
|
||||||
-> &'tcx ty::TypeckTables<'tcx> {
|
/// returns `None`.
|
||||||
// Closures' tables come from their outermost function,
|
///
|
||||||
// as they are part of the same "inference environment".
|
/// If this function returns "some", then `typeck_tables(def_id)` will
|
||||||
let outer_def_id = tcx.closure_base_def_id(def_id);
|
/// succeed; if it returns `None`, then `typeck_tables(def_id)` may or
|
||||||
if outer_def_id != def_id {
|
/// may not succeed. In some cases where this function returns `None`
|
||||||
return tcx.typeck_tables_of(outer_def_id);
|
/// (notably closures), `typeck_tables(def_id)` would wind up
|
||||||
}
|
/// redirecting to the owning function.
|
||||||
|
fn primary_body_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
id: ast::NodeId)
|
||||||
let span = tcx.hir.span(id);
|
-> Option<(hir::BodyId, Option<&'tcx hir::FnDecl>)>
|
||||||
let unsupported = || {
|
{
|
||||||
span_bug!(span, "can't type-check body of {:?}", def_id);
|
match tcx.hir.get(id) {
|
||||||
};
|
|
||||||
|
|
||||||
// Figure out what primary body this item has.
|
|
||||||
let mut fn_decl = None;
|
|
||||||
let body_id = match tcx.hir.get(id) {
|
|
||||||
hir::map::NodeItem(item) => {
|
hir::map::NodeItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemConst(_, body) |
|
hir::ItemConst(_, body) |
|
||||||
hir::ItemStatic(_, _, body) => body,
|
hir::ItemStatic(_, _, body) =>
|
||||||
hir::ItemFn(ref decl, .., body) => {
|
Some((body, None)),
|
||||||
fn_decl = Some(decl);
|
hir::ItemFn(ref decl, .., body) =>
|
||||||
body
|
Some((body, Some(decl))),
|
||||||
}
|
_ =>
|
||||||
_ => unsupported()
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::map::NodeTraitItem(item) => {
|
hir::map::NodeTraitItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::TraitItemKind::Const(_, Some(body)) => body,
|
hir::TraitItemKind::Const(_, Some(body)) =>
|
||||||
hir::TraitItemKind::Method(ref sig,
|
Some((body, None)),
|
||||||
hir::TraitMethod::Provided(body)) => {
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) =>
|
||||||
fn_decl = Some(&sig.decl);
|
Some((body, Some(&sig.decl))),
|
||||||
body
|
_ =>
|
||||||
}
|
None,
|
||||||
_ => unsupported()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::map::NodeImplItem(item) => {
|
hir::map::NodeImplItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ImplItemKind::Const(_, body) => body,
|
hir::ImplItemKind::Const(_, body) =>
|
||||||
hir::ImplItemKind::Method(ref sig, body) => {
|
Some((body, None)),
|
||||||
fn_decl = Some(&sig.decl);
|
hir::ImplItemKind::Method(ref sig, body) =>
|
||||||
body
|
Some((body, Some(&sig.decl))),
|
||||||
}
|
_ =>
|
||||||
_ => unsupported()
|
None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::map::NodeExpr(expr) => {
|
hir::map::NodeExpr(expr) => {
|
||||||
|
@ -723,15 +718,47 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
// Assume that everything other than closures
|
// Assume that everything other than closures
|
||||||
// is a constant "initializer" expression.
|
// is a constant "initializer" expression.
|
||||||
match expr.node {
|
match expr.node {
|
||||||
hir::ExprClosure(..) => {
|
hir::ExprClosure(..) =>
|
||||||
// We should've bailed out above for closures.
|
None,
|
||||||
span_bug!(expr.span, "unexpected closure")
|
_ =>
|
||||||
}
|
Some((hir::BodyId { node_id: expr.id }, None)),
|
||||||
_ => hir::BodyId { node_id: expr.id }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unsupported()
|
_ => None,
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
def_id: DefId)
|
||||||
|
-> bool {
|
||||||
|
// Closures' tables come from their outermost function,
|
||||||
|
// as they are part of the same "inference environment".
|
||||||
|
let outer_def_id = tcx.closure_base_def_id(def_id);
|
||||||
|
if outer_def_id != def_id {
|
||||||
|
return tcx.has_typeck_tables(outer_def_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
|
primary_body_of(tcx, id).is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
def_id: DefId)
|
||||||
|
-> &'tcx ty::TypeckTables<'tcx> {
|
||||||
|
// Closures' tables come from their outermost function,
|
||||||
|
// as they are part of the same "inference environment".
|
||||||
|
let outer_def_id = tcx.closure_base_def_id(def_id);
|
||||||
|
if outer_def_id != def_id {
|
||||||
|
return tcx.typeck_tables_of(outer_def_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
|
let span = tcx.hir.span(id);
|
||||||
|
|
||||||
|
// Figure out what primary body this item has.
|
||||||
|
let (body_id, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
|
||||||
|
span_bug!(span, "can't type-check body of {:?}", def_id);
|
||||||
|
});
|
||||||
let body = tcx.hir.body(body_id);
|
let body = tcx.hir.body(body_id);
|
||||||
|
|
||||||
Inherited::build(tcx, id).enter(|inh| {
|
Inherited::build(tcx, id).enter(|inh| {
|
||||||
|
|
|
@ -63,9 +63,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
|
||||||
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
let mut used_trait_imports = DefIdSet();
|
let mut used_trait_imports = DefIdSet();
|
||||||
for &body_id in tcx.hir.krate().bodies.keys() {
|
for &body_id in tcx.hir.krate().bodies.keys() {
|
||||||
let item_id = tcx.hir.body_owner(body_id);
|
let item_def_id = tcx.hir.body_owner_def_id(body_id);
|
||||||
let item_def_id = tcx.hir.local_def_id(item_id);
|
|
||||||
|
|
||||||
let tables = tcx.typeck_tables_of(item_def_id);
|
let tables = tcx.typeck_tables_of(item_def_id);
|
||||||
let imports = &tables.used_trait_imports;
|
let imports = &tables.used_trait_imports;
|
||||||
debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
|
debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
|
||||||
|
|
Loading…
Reference in New Issue