Auto merge of #51882 - varkor:check-type_dependent_defs, r=estebank

Always check type_dependent_defs

Directly indexing into `type_dependent_defs` has caused multiple ICEs in the past (https://github.com/rust-lang/rust/issues/46771, https://github.com/rust-lang/rust/issues/49241, etc.) and is almost certainly responsible for #51798 too. This PR ensures we always check `type_dependent_defs` first, which should prevent any more of these (or at least make them easier to track down).
This commit is contained in:
bors 2018-07-01 08:41:50 +00:00
commit d94b804863
5 changed files with 28 additions and 11 deletions

View File

@ -96,7 +96,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
}
fn lookup_and_handle_method(&mut self, id: hir::HirId) {
self.check_def_id(self.tables.type_dependent_defs()[id].def_id());
if let Some(def) = self.tables.type_dependent_defs().get(id) {
self.check_def_id(def.def_id());
} else {
bug!("no type-dependent def for method");
}
}
fn handle_field_access(&mut self, lhs: &hir::Expr, node_id: ast::NodeId) {

View File

@ -120,7 +120,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
Some(self.tables.qpath_def(qpath, expr.hir_id))
}
hir::ExprMethodCall(..) => {
Some(self.tables.type_dependent_defs()[expr.hir_id])
self.tables.type_dependent_defs().get(expr.hir_id).cloned()
}
_ => None
};

View File

@ -1004,10 +1004,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion {
// Check for method calls and overloaded operators.
if cx.tables.is_method_call(expr) {
let hir_id = cx.tcx.hir.definitions().node_to_hir_id(id);
let def_id = cx.tables.type_dependent_defs()[hir_id].def_id();
let substs = cx.tables.node_substs(hir_id);
if method_call_refers_to_method(cx, method, def_id, substs, id) {
return true;
if let Some(def) = cx.tables.type_dependent_defs().get(hir_id) {
let def_id = def.def_id();
let substs = cx.tables.node_substs(hir_id);
if method_call_refers_to_method(cx, method, def_id, substs, id) {
return true;
}
} else {
cx.tcx.sess.delay_span_bug(expr.span,
"no type-dependent def for method call");
}
}

View File

@ -692,8 +692,11 @@ fn method_callee<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
-> Expr<'tcx> {
let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id);
let (def_id, substs) = custom_callee.unwrap_or_else(|| {
(cx.tables().type_dependent_defs()[expr.hir_id].def_id(),
cx.tables().node_substs(expr.hir_id))
if let Some(def) = cx.tables().type_dependent_defs().get(expr.hir_id) {
(def.def_id(), cx.tables().node_substs(expr.hir_id))
} else {
span_bug!(expr.span, "no type-dependent def for method callee")
}
});
let ty = cx.tcx().mk_fn_def(def_id, substs);
Expr {

View File

@ -795,10 +795,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
}
hir::ExprMethodCall(_, span, _) => {
// Method calls have to be checked specially.
let def_id = self.tables.type_dependent_defs()[expr.hir_id].def_id();
self.span = span;
if self.tcx.type_of(def_id).visit_with(self) {
return;
if let Some(def) = self.tables.type_dependent_defs().get(expr.hir_id) {
let def_id = def.def_id();
if self.tcx.type_of(def_id).visit_with(self) {
return;
}
} else {
self.tcx.sess.delay_span_bug(expr.span,
"no type-dependent def for method call");
}
}
_ => {}