From 4dead776e196832320f0c49a6e6d779934b97193 Mon Sep 17 00:00:00 2001 From: Matthias Richter Date: Tue, 7 Nov 2023 16:01:52 +0100 Subject: [PATCH] add type details to unnecessary_fallible_conversions note --- .../unnecessary_fallible_conversions.rs | 38 ++++++++++++++----- .../unnecessary_fallible_conversions.stderr | 3 ++ ...sary_fallible_conversions_unfixable.stderr | 11 ++++++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_fallible_conversions.rs b/clippy_lints/src/methods/unnecessary_fallible_conversions.rs index bb32b1bb7fc..89cf20c14fc 100644 --- a/clippy_lints/src/methods/unnecessary_fallible_conversions.rs +++ b/clippy_lints/src/methods/unnecessary_fallible_conversions.rs @@ -1,10 +1,11 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::get_parent_expr; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::LateContext; use rustc_middle::ty; +use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_span::{sym, Span}; use super::UNNECESSARY_FALLIBLE_CONVERSIONS; @@ -42,6 +43,7 @@ fn check<'tcx>( // (else there would be conflicting impls, even with #![feature(spec)]), so we don't even need to check // what `>::Error` is: it's always `Infallible` && implements_trait(cx, self_ty, from_into_trait, &[other_ty]) + && let Some(other_ty) = other_ty.as_type() { let parent_unwrap_call = get_parent_expr(cx, expr).and_then(|parent| { if let ExprKind::MethodCall(path, .., span) = parent.kind @@ -52,8 +54,7 @@ fn check<'tcx>( None } }); - - let (sugg, span, applicability) = match kind { + let (source_ty, target_ty, sugg, span, applicability) = match kind { FunctionKind::TryIntoMethod if let Some(unwrap_span) = parent_unwrap_call => { // Extend the span to include the unwrap/expect call: // `foo.try_into().expect("..")` @@ -63,24 +64,41 @@ fn check<'tcx>( // so that can be machine-applicable ( + self_ty, + other_ty, "into()", primary_span.with_hi(unwrap_span.hi()), Applicability::MachineApplicable, ) }, - FunctionKind::TryFromFunction => ("From::from", primary_span, Applicability::Unspecified), - FunctionKind::TryIntoFunction => ("Into::into", primary_span, Applicability::Unspecified), - FunctionKind::TryIntoMethod => ("into", primary_span, Applicability::Unspecified), + FunctionKind::TryFromFunction => ( + other_ty, + self_ty, + "From::from", + primary_span, + Applicability::Unspecified, + ), + FunctionKind::TryIntoFunction => ( + self_ty, + other_ty, + "Into::into", + primary_span, + Applicability::Unspecified, + ), + FunctionKind::TryIntoMethod => (self_ty, other_ty, "into", primary_span, Applicability::Unspecified), }; - span_lint_and_sugg( + span_lint_and_then( cx, UNNECESSARY_FALLIBLE_CONVERSIONS, span, "use of a fallible conversion when an infallible one could be used", - "use", - sugg.into(), - applicability, + |diag| { + with_forced_trimmed_paths!({ + diag.note(format!("converting `{source_ty}` to `{target_ty}` cannot fail")); + }); + diag.span_suggestion(span, "use", sugg, applicability); + }, ); } } diff --git a/tests/ui/unnecessary_fallible_conversions.stderr b/tests/ui/unnecessary_fallible_conversions.stderr index b918fdf774b..26b152515ac 100644 --- a/tests/ui/unnecessary_fallible_conversions.stderr +++ b/tests/ui/unnecessary_fallible_conversions.stderr @@ -4,6 +4,7 @@ error: use of a fallible conversion when an infallible one could be used LL | let _: i64 = 0i32.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^ help: use: `into()` | + = note: converting `i32` to `i64` cannot fail = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` @@ -12,6 +13,8 @@ error: use of a fallible conversion when an infallible one could be used | LL | let _: i64 = 0i32.try_into().expect("can't happen"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `into()` + | + = note: converting `i32` to `i64` cannot fail error: aborting due to 2 previous errors diff --git a/tests/ui/unnecessary_fallible_conversions_unfixable.stderr b/tests/ui/unnecessary_fallible_conversions_unfixable.stderr index 286decf8f35..033de0e9250 100644 --- a/tests/ui/unnecessary_fallible_conversions_unfixable.stderr +++ b/tests/ui/unnecessary_fallible_conversions_unfixable.stderr @@ -4,6 +4,7 @@ error: use of a fallible conversion when an infallible one could be used LL | let _: Result = 0i64.try_into(); | ^^^^^^^^ help: use: `into` | + = note: converting `i64` to `Foo` cannot fail = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]` @@ -12,30 +13,40 @@ error: use of a fallible conversion when an infallible one could be used | LL | let _: Result = i64::try_into(0i64); | ^^^^^^^^^^^^^ help: use: `Into::into` + | + = note: converting `i64` to `Foo` cannot fail error: use of a fallible conversion when an infallible one could be used --> $DIR/unnecessary_fallible_conversions_unfixable.rs:31:29 | LL | let _: Result = Foo::try_from(0i64); | ^^^^^^^^^^^^^ help: use: `From::from` + | + = note: converting `i64` to `Foo` cannot fail error: use of a fallible conversion when an infallible one could be used --> $DIR/unnecessary_fallible_conversions_unfixable.rs:34:34 | LL | let _: Result = 0i32.try_into(); | ^^^^^^^^ help: use: `into` + | + = note: converting `i32` to `i64` cannot fail error: use of a fallible conversion when an infallible one could be used --> $DIR/unnecessary_fallible_conversions_unfixable.rs:36:29 | LL | let _: Result = i32::try_into(0i32); | ^^^^^^^^^^^^^ help: use: `Into::into` + | + = note: converting `i32` to `i64` cannot fail error: use of a fallible conversion when an infallible one could be used --> $DIR/unnecessary_fallible_conversions_unfixable.rs:38:29 | LL | let _: Result = <_>::try_from(0i32); | ^^^^^^^^^^^^^ help: use: `From::from` + | + = note: converting `i32` to `i64` cannot fail error: aborting due to 6 previous errors