Improve error messages

This commit is contained in:
Ryan Levick 2021-01-12 14:58:51 +01:00 committed by Ryan Levick
parent 316e9db0cf
commit 49f32e0c8e
2 changed files with 25 additions and 21 deletions

View file

@ -39,7 +39,7 @@ declare_lint_pass!(NoopMethodCall => [NOOP_METHOD_CALL]);
impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// We only care about method calls // We only care about method calls
if let ExprKind::MethodCall(call, ..) = expr.kind { if let ExprKind::MethodCall(call, _, elements, _) = expr.kind {
// Get the `DefId` only when dealing with an `AssocFn` // Get the `DefId` only when dealing with an `AssocFn`
if let Some((DefKind::AssocFn, did)) = if let Some((DefKind::AssocFn, did)) =
cx.typeck_results().type_dependent_def(expr.hir_id) cx.typeck_results().type_dependent_def(expr.hir_id)
@ -70,15 +70,23 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
.iter() .iter()
.any(|s| cx.tcx.is_diagnostic_item(*s, i.def_id())) .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 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
);
cx.struct_span_lint(NOOP_METHOD_CALL, expr_span, |lint| { let span = expr_span.with_lo(receiver.span.hi());
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
let method = &call.ident.name; let method = &call.ident.name;
let message = format!("call to `.{}()` on a reference in this situation does nothing", &method); let message = format!("call to `.{}()` on a reference in this situation does nothing", &method);
lint.build(&message) lint.build(&message)
.span_label(expr_span, "unnecessary method call") .span_label(span, "unnecessary method call")
.note("the type the method is being called on and the return type are functionally equivalent.") .note(&note)
.note("therefore, the method call doesn't actually do anything and can be removed.")
.emit() .emit()
}); });
} }

View file

@ -1,39 +1,35 @@
warning: call to `.clone()` on a reference in this situation does nothing warning: call to `.clone()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:24:32 --> $DIR/noop-method-call.rs:24:35
| |
LL | let foo_clone: &Foo<u32> = foo.clone(); LL | let foo_clone: &Foo<u32> = foo.clone();
| ^^^^^^^^^^^ unnecessary method call | ^^^^^^^^ unnecessary method call
| |
= note: `#[warn(noop_method_call)]` on by default = note: `#[warn(noop_method_call)]` on by default
= note: the type the method is being called on and the return type are functionally equivalent. = note: the type `&Foo<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed.
= note: therefore, the method call doesn't actually do anything and can be removed.
warning: call to `.deref()` on a reference in this situation does nothing warning: call to `.deref()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:31:39 --> $DIR/noop-method-call.rs:31:44
| |
LL | let derefed: &DerefExample<u32> = deref.deref(); LL | let derefed: &DerefExample<u32> = deref.deref();
| ^^^^^^^^^^^^^ unnecessary method call | ^^^^^^^^ unnecessary method call
| |
= note: the type the method is being called on and the return type are functionally equivalent. = note: the type `&&DerefExample<u32>` which `deref` is being called on is the same as the type returned from `deref`, so the method call does not do anything and can be removed.
= note: therefore, the method call doesn't actually do anything and can be removed.
warning: call to `.borrow()` on a reference in this situation does nothing warning: call to `.borrow()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:38:31 --> $DIR/noop-method-call.rs:38:32
| |
LL | let borrowed: &Foo<u32> = a.borrow(); LL | let borrowed: &Foo<u32> = a.borrow();
| ^^^^^^^^^^ unnecessary method call | ^^^^^^^^^ unnecessary method call
| |
= note: the type the method is being called on and the return type are functionally equivalent. = note: the type `&&Foo<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed.
= note: therefore, the method call doesn't actually do anything and can be removed.
warning: call to `.clone()` on a reference in this situation does nothing warning: call to `.clone()` on a reference in this situation does nothing
--> $DIR/noop-method-call.rs:47:5 --> $DIR/noop-method-call.rs:47:8
| |
LL | foo.clone(); LL | foo.clone();
| ^^^^^^^^^^^ unnecessary method call | ^^^^^^^^ unnecessary method call
| |
= note: the type the method is being called on and the return type are functionally equivalent. = note: the type `&Foo<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed.
= note: therefore, the method call doesn't actually do anything and can be removed.
warning: 4 warnings emitted warning: 4 warnings emitted