about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-11-11 22:51:27 +0000
committerbors <bors@rust-lang.org>2023-11-11 22:51:27 +0000
commit8ee9a9c549601216cce8cfdd5545cc4d671a914d (patch)
tree56cc58ee480510edcc778117508e1cc4e9eec892
parentd487579efd3c6b7766f820bbe4b6be0f6d420dad (diff)
parent4dead776e196832320f0c49a6e6d779934b97193 (diff)
downloadrust-8ee9a9c549601216cce8cfdd5545cc4d671a914d.tar.gz
rust-8ee9a9c549601216cce8cfdd5545cc4d671a914d.zip
Auto merge of #11767 - matthri:unnecessary-fallible-conversions-ext-notes, r=blyxyas
Add type details to unnecessary_fallible_conversions note

fixes: #11753

changelog: [`unnecessary_fallible_conversions`]: add type details to lint note
-rw-r--r--clippy_lints/src/methods/unnecessary_fallible_conversions.rs38
-rw-r--r--tests/ui/unnecessary_fallible_conversions.stderr3
-rw-r--r--tests/ui/unnecessary_fallible_conversions_unfixable.stderr11
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 `<T as TryFrom<U>>::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<Foo, _> = 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<Foo, _> = 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, _> = 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<i64, _> = 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<i64, _> = 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<i64, _> = <_>::try_from(0i32);
    |                             ^^^^^^^^^^^^^ help: use: `From::from`
+   |
+   = note: converting `i32` to `i64` cannot fail
 
 error: aborting due to 6 previous errors