Rollup merge of #81176 - camsteffen:qpath-res, r=oli-obk

Improve safety of `LateContext::qpath_res`

This is my first rustc code change, inspired by hacking on clippy!

The first change is to clear cached `TypeckResults` from `LateContext` when visiting a nested item. I took a hint from [here](5e91c4ecc0/compiler/rustc_privacy/src/lib.rs (L1300)).

Clippy has a `qpath_res` util function to avoid a possible ICE in `LateContext::qpath_res`. But the docs of `LateContext::qpath_res` promise no ICE. So this updates the `LateContext` method to keep its promises, and removes the util function.

Related: rust-lang/rust-clippy#4545

CC ````````````@eddyb```````````` since you've done related work
CC ````````````@flip1995```````````` FYI
This commit is contained in:
Yuki Okushi 2021-01-29 09:17:32 +09:00 committed by GitHub
commit 0c5fccea22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 57 additions and 58 deletions

View file

@ -746,6 +746,14 @@ impl<'tcx> LateContext<'tcx> {
hir::QPath::Resolved(_, ref path) => path.res,
hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
.maybe_typeck_results()
.filter(|typeck_results| typeck_results.hir_owner == id.owner)
.or_else(|| {
if self.tcx.has_typeck_results(id.owner.to_def_id()) {
Some(self.tcx.typeck(id.owner))
} else {
None
}
})
.and_then(|typeck_results| typeck_results.type_dependent_def(id))
.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
}

View file

@ -140,6 +140,8 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) {
let generics = self.context.generics.take();
self.context.generics = it.kind.generics();
let old_cached_typeck_results = self.context.cached_typeck_results.take();
let old_enclosing_body = self.context.enclosing_body.take();
self.with_lint_attrs(it.hir_id, &it.attrs, |cx| {
cx.with_param_env(it.hir_id, |cx| {
lint_callback!(cx, check_item, it);
@ -147,6 +149,8 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
lint_callback!(cx, check_item_post, it);
});
});
self.context.enclosing_body = old_enclosing_body;
self.context.cached_typeck_results.set(old_cached_typeck_results);
self.context.generics = generics;
}