diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2024-01-13 13:14:16 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2024-01-13 13:19:55 +0100 |
| commit | e02535696948a921937e4768421cf4cf9b8e7a53 (patch) | |
| tree | 124fcb26223e1104aad70ac118a8c134a8f5b1b9 | |
| parent | a71211d0b52c01f1b37fe544e0e13fd1bdc31979 (diff) | |
| download | rust-e02535696948a921937e4768421cf4cf9b8e7a53.tar.gz rust-e02535696948a921937e4768421cf4cf9b8e7a53.zip | |
from_over_into: suggest a correct conversion to ()
| -rw-r--r-- | clippy_lints/src/from_over_into.rs | 9 | ||||
| -rw-r--r-- | tests/ui/from_over_into.fixed | 8 | ||||
| -rw-r--r-- | tests/ui/from_over_into.rs | 8 | ||||
| -rw-r--r-- | tests/ui/from_over_into.stderr | 16 |
4 files changed, 37 insertions, 4 deletions
diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index fa1f98ba013..93527bcdf5c 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -6,8 +6,8 @@ use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_path, Visitor}; use rustc_hir::{ - GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path, PathSegment, Ty, - TyKind, + FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path, + PathSegment, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter::OnlyBodies; @@ -181,6 +181,9 @@ fn convert_to_from( let from = snippet_opt(cx, self_ty.span)?; let into = snippet_opt(cx, target_ty.span)?; + let return_type = matches!(sig.decl.output, FnRetTy::Return(_)) + .then_some(String::from("Self")) + .unwrap_or_default(); let mut suggestions = vec![ // impl Into<T> for U -> impl From<T> for U // ~~~~ ~~~~ @@ -199,7 +202,7 @@ fn convert_to_from( (self_ident.span, format!("val: {from}")), // fn into(self) -> T -> fn into(self) -> Self // ~ ~~~~ - (sig.decl.output.span(), String::from("Self")), + (sig.decl.output.span(), return_type), ]; let mut finder = SelfFinder { diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed index 18d285693e6..4a68505ee0b 100644 --- a/tests/ui/from_over_into.fixed +++ b/tests/ui/from_over_into.fixed @@ -89,4 +89,12 @@ fn msrv_1_41() { } } +fn issue_12138() { + struct Hello; + + impl From<Hello> for () { + fn from(val: Hello) {} + } +} + fn main() {} diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs index 779ef709e92..bf3ed0c2b64 100644 --- a/tests/ui/from_over_into.rs +++ b/tests/ui/from_over_into.rs @@ -89,4 +89,12 @@ fn msrv_1_41() { } } +fn issue_12138() { + struct Hello; + + impl Into<()> for Hello { + fn into(self) {} + } +} + fn main() {} diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr index 784843ce5fd..f1370ed844f 100644 --- a/tests/ui/from_over_into.stderr +++ b/tests/ui/from_over_into.stderr @@ -86,5 +86,19 @@ LL ~ fn from(val: Vec<T>) -> Self { LL ~ FromOverInto(val) | -error: aborting due to 6 previous errors +error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true + --> $DIR/from_over_into.rs:95:5 + | +LL | impl Into<()> for Hello { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see + https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence +help: replace the `Into` implementation with `From<issue_12138::Hello>` + | +LL ~ impl From<Hello> for () { +LL ~ fn from(val: Hello) {} + | + +error: aborting due to 7 previous errors |
