diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2021-01-12 18:37:32 -0800 |
|---|---|---|
| committer | Ryan Levick <me@ryanlevick.com> | 2021-03-03 11:22:56 +0100 |
| commit | e48670c34a3f5ab3fe9defcc61861999f3f14e93 (patch) | |
| tree | a082d55e96c082b3bf163f7aaecd56c6b4b077bf /compiler/rustc_lint/src/noop_method_call.rs | |
| parent | 49f32e0c8e78948210654299a8c19b2e0f0cbfa9 (diff) | |
| download | rust-e48670c34a3f5ab3fe9defcc61861999f3f14e93.tar.gz rust-e48670c34a3f5ab3fe9defcc61861999f3f14e93.zip | |
Increase accuracy of lint trigger
Diffstat (limited to 'compiler/rustc_lint/src/noop_method_call.rs')
| -rw-r--r-- | compiler/rustc_lint/src/noop_method_call.rs | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 1aa4a986cd1..04d87dc9592 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -62,33 +62,45 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { // Resolve the trait method instance if let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) { // Check that it implements the noop diagnostic - if [ - sym::noop_method_borrow, - sym::noop_method_clone, - sym::noop_method_deref, + for (s, peel_ref) in [ + (sym::noop_method_borrow, true), + (sym::noop_method_clone, false), + (sym::noop_method_deref, true), ] .iter() - .any(|s| cx.tcx.is_diagnostic_item(*s, i.def_id())) { - let method = &call.ident.name; - let receiver = &elements[0]; - let receiver_ty = cx.typeck_results().expr_ty(receiver); - let expr_span = expr.span; - let note = format!( - "the type `{:?}` which `{}` is being called on is the same as the type returned from `{}`, \ - so the method call does not do anything and can be removed.", - receiver_ty, method, method - ); - - let span = expr_span.with_lo(receiver.span.hi()); - cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| { + if cx.tcx.is_diagnostic_item(*s, i.def_id()) { let method = &call.ident.name; - let message = format!("call to `.{}()` on a reference in this situation does nothing", &method); - lint.build(&message) - .span_label(span, "unnecessary method call") - .note(¬e) - .emit() - }); + let receiver = &elements[0]; + let receiver_ty = cx.typeck_results().expr_ty(receiver); + let receiver_ty = match receiver_ty.kind() { + // Remove one borrow from the receiver as all the trait methods + // we care about here have a `&self` receiver. + ty::Ref(_, ty, _) if *peel_ref => ty, + _ => receiver_ty, + }; + let expr_ty = cx.typeck_results().expr_ty_adjusted(expr); + if receiver_ty != expr_ty { + return; + } + let expr_span = expr.span; + let note = format!( + "the type `{:?}` which `{}` is being called on is the same as \ + the type returned from `{}`, so the method call does not do \ + anything and can be removed", + receiver_ty, method, method, + ); + + let span = expr_span.with_lo(receiver.span.hi()); + cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| { + let method = &call.ident.name; + let message = format!("call to `.{}()` on a reference in this situation does nothing", &method); + lint.build(&message) + .span_label(span, "unnecessary method call") + .note(¬e) + .emit() + }); + } } } } |
