Skip to content

Commit

Permalink
add type details to unnecessary_fallible_conversions note
Browse files Browse the repository at this point in the history
  • Loading branch information
matthri committed Nov 7, 2023
1 parent 6d9516a commit f9b6361
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
41 changes: 30 additions & 11 deletions clippy_lints/src/methods/unnecessary_fallible_conversions.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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("..")`
Expand All @@ -63,25 +64,43 @@ 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}` which cannot fail"));

diag.span_suggestion(span, "use", sugg, applicability);
})
},
)
}
}

Expand Down
3 changes: 3 additions & 0 deletions tests/ui/unnecessary_fallible_conversions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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` which cannot fail
= note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`

Expand All @@ -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` which cannot fail

error: aborting due to 2 previous errors

11 changes: 11 additions & 0 deletions tests/ui/unnecessary_fallible_conversions_unfixable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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` which cannot fail
= note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`

Expand All @@ -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` which 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` which 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` which 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` which 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` which cannot fail

error: aborting due to 6 previous errors

0 comments on commit f9b6361

Please sign in to comment.