Normalize substs before resolving instance in NoopMethodCall lint

This commit is contained in:
Michael Goulet 2022-09-29 22:03:03 +00:00
parent f83e0266cf
commit 8c600120e6
2 changed files with 29 additions and 5 deletions

View File

@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
}; };
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow` // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
// traits and ignore any other method call. // traits and ignore any other method call.
let (trait_id, did) = match cx.typeck_results().type_dependent_def(expr.hir_id) { let did = match cx.typeck_results().type_dependent_def(expr.hir_id) {
// Verify we are dealing with a method/associated function. // Verify we are dealing with a method/associated function.
Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) { Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) {
// Check that we're dealing with a trait method for one of the traits we care about. // Check that we're dealing with a trait method for one of the traits we care about.
@ -56,21 +56,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
Some(sym::Borrow | sym::Clone | sym::Deref) Some(sym::Borrow | sym::Clone | sym::Deref)
) => ) =>
{ {
(trait_id, did) did
} }
_ => return, _ => return,
}, },
_ => return, _ => return,
}; };
let substs = cx.typeck_results().node_substs(expr.hir_id); let substs = cx
.tcx
.normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id));
if substs.needs_subst() { if substs.needs_subst() {
// We can't resolve on types that require monomorphization, so we don't handle them if // We can't resolve on types that require monomorphization, so we don't handle them if
// we need to perform substitution. // we need to perform substitution.
return; return;
} }
let param_env = cx.tcx.param_env(trait_id);
// Resolve the trait method instance. // Resolve the trait method instance.
let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) else { let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, substs) else {
return return
}; };
// (Re)check that it implements the noop diagnostic. // (Re)check that it implements the noop diagnostic.

View File

@ -0,0 +1,23 @@
// check-pass
// Checks that the NoopMethodCall lint doesn't call Instance::resolve on unresolved consts
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
#[derive(Debug, Clone)]
pub struct Aes128CipherKey([u8; Aes128Cipher::KEY_LEN]);
impl Aes128CipherKey {
pub fn new(key: &[u8; Aes128Cipher::KEY_LEN]) -> Self {
Self(key.clone())
}
}
#[derive(Debug, Clone)]
pub struct Aes128Cipher;
impl Aes128Cipher {
const KEY_LEN: usize = 16;
}
fn main() {}