Add tests and support two more noop methods

This commit is contained in:
Ryan Levick 2021-01-05 16:14:39 +01:00 committed by Ryan Levick
parent 040735c110
commit f49ed7a6b7
7 changed files with 89 additions and 5 deletions

View File

@ -54,11 +54,19 @@ 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 cx.tcx.is_diagnostic_item(sym::ref_clone_method, i.def_id()) {
tracing::debug!("Resolves to: {:?}", i.def_id());
if [
sym::noop_method_borrow,
sym::noop_method_clone,
sym::noop_method_deref,
]
.iter()
.any(|s| cx.tcx.is_diagnostic_item(*s, i.def_id()))
{
let span = expr.span;
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
let message = "Call to noop method";
let message = "call to noop method";
lint.build(&message).emit()
});
}

View File

@ -789,6 +789,9 @@ symbols! {
none_error,
nontemporal_store,
nontrapping_dash_fptoint: "nontrapping-fptoint",
noop_method_borrow,
noop_method_clone,
noop_method_deref,
noreturn,
nostack,
not,
@ -915,7 +918,6 @@ symbols! {
receiver,
recursion_limit,
reexport_test_harness_main,
ref_clone_method,
reference,
reflect,
reg,

View File

@ -219,6 +219,7 @@ impl<T: ?Sized> BorrowMut<T> for T {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for &T {
#[rustc_diagnostic_item = "noop_method_borrow"]
fn borrow(&self) -> &T {
&**self
}

View File

@ -104,7 +104,6 @@
/// [impls]: #implementors
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "clone"]
#[rustc_diagnostic_item = "Clone"]
pub trait Clone: Sized {
/// Returns a copy of the value.
///
@ -222,7 +221,7 @@ mod impls {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for &T {
#[inline]
#[rustc_diagnostic_item = "ref_clone_method"]
#[rustc_diagnostic_item = "noop_method_clone"]
fn clone(&self) -> Self {
*self
}

View File

@ -78,6 +78,7 @@ pub trait Deref {
impl<T: ?Sized> Deref for &T {
type Target = T;
#[rustc_diagnostic_item = "noop_method_deref"]
fn deref(&self) -> &T {
*self
}

View File

@ -0,0 +1,45 @@
// check-pass
#![allow(unused)]
use std::borrow::Borrow;
use std::ops::Deref;
struct Foo<T>(T);
#[derive(Clone)]
struct Bar<T>(T);
struct DerefExample<T>(T);
impl<T> Deref for DerefExample<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let foo = &Foo(1u32);
let foo_clone: &Foo<u32> = foo.clone(); //~ WARNING call to noop method
let bar = &Bar(1u32);
let bar_clone: Bar<u32> = bar.clone();
let deref = &&DerefExample(12u32);
let derefed: &DerefExample<u32> = deref.deref(); //~ WARNING call to noop method
let deref = &DerefExample(12u32);
let derefed: &u32 = deref.deref();
let a = &&Foo(1u32);
let borrowed: &Foo<u32> = a.borrow(); //~ WARNING call to noop method
}
fn generic<T>(foo: &Foo<T>) {
foo.clone();
}
fn non_generic(foo: &Foo<u32>) {
foo.clone(); //~ WARNING call to noop method
}

View File

@ -0,0 +1,28 @@
warning: call to noop method
--> $DIR/noop-method-call.rs:24:32
|
LL | let foo_clone: &Foo<u32> = foo.clone();
| ^^^^^^^^^^^
|
= note: `#[warn(noop_method_call)]` on by default
warning: call to noop method
--> $DIR/noop-method-call.rs:30:39
|
LL | let derefed: &DerefExample<u32> = deref.deref();
| ^^^^^^^^^^^^^
warning: call to noop method
--> $DIR/noop-method-call.rs:36:31
|
LL | let borrowed: &Foo<u32> = a.borrow();
| ^^^^^^^^^^
warning: call to noop method
--> $DIR/noop-method-call.rs:44:5
|
LL | foo.clone();
| ^^^^^^^^^^^
warning: 4 warnings emitted