Add tests and support two more noop methods
This commit is contained in:
parent
040735c110
commit
f49ed7a6b7
@ -54,11 +54,19 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
|
|||||||
// Resolve the trait method instance
|
// Resolve the trait method instance
|
||||||
if let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) {
|
if let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) {
|
||||||
// Check that it implements the noop diagnostic
|
// 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;
|
let span = expr.span;
|
||||||
|
|
||||||
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
|
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()
|
lint.build(&message).emit()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -789,6 +789,9 @@ symbols! {
|
|||||||
none_error,
|
none_error,
|
||||||
nontemporal_store,
|
nontemporal_store,
|
||||||
nontrapping_dash_fptoint: "nontrapping-fptoint",
|
nontrapping_dash_fptoint: "nontrapping-fptoint",
|
||||||
|
noop_method_borrow,
|
||||||
|
noop_method_clone,
|
||||||
|
noop_method_deref,
|
||||||
noreturn,
|
noreturn,
|
||||||
nostack,
|
nostack,
|
||||||
not,
|
not,
|
||||||
@ -915,7 +918,6 @@ symbols! {
|
|||||||
receiver,
|
receiver,
|
||||||
recursion_limit,
|
recursion_limit,
|
||||||
reexport_test_harness_main,
|
reexport_test_harness_main,
|
||||||
ref_clone_method,
|
|
||||||
reference,
|
reference,
|
||||||
reflect,
|
reflect,
|
||||||
reg,
|
reg,
|
||||||
|
@ -219,6 +219,7 @@ impl<T: ?Sized> BorrowMut<T> for T {
|
|||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: ?Sized> Borrow<T> for &T {
|
impl<T: ?Sized> Borrow<T> for &T {
|
||||||
|
#[rustc_diagnostic_item = "noop_method_borrow"]
|
||||||
fn borrow(&self) -> &T {
|
fn borrow(&self) -> &T {
|
||||||
&**self
|
&**self
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,6 @@
|
|||||||
/// [impls]: #implementors
|
/// [impls]: #implementors
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[lang = "clone"]
|
#[lang = "clone"]
|
||||||
#[rustc_diagnostic_item = "Clone"]
|
|
||||||
pub trait Clone: Sized {
|
pub trait Clone: Sized {
|
||||||
/// Returns a copy of the value.
|
/// Returns a copy of the value.
|
||||||
///
|
///
|
||||||
@ -222,7 +221,7 @@ mod impls {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<T: ?Sized> Clone for &T {
|
impl<T: ?Sized> Clone for &T {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_diagnostic_item = "ref_clone_method"]
|
#[rustc_diagnostic_item = "noop_method_clone"]
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ pub trait Deref {
|
|||||||
impl<T: ?Sized> Deref for &T {
|
impl<T: ?Sized> Deref for &T {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
|
#[rustc_diagnostic_item = "noop_method_deref"]
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
|
45
src/test/ui/lint/noop-method-call.rs
Normal file
45
src/test/ui/lint/noop-method-call.rs
Normal 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
|
||||||
|
}
|
28
src/test/ui/lint/noop-method-call.stderr
Normal file
28
src/test/ui/lint/noop-method-call.stderr
Normal 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
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user