diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs index 8621504c1b47..cc3c35f48635 100644 --- a/clippy_lints/src/from_over_into.rs +++ b/clippy_lints/src/from_over_into.rs @@ -10,7 +10,7 @@ use rustc_hir::{ TyKind, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::{hir::nested_filter::OnlyBodies, ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::{kw, sym}; use rustc_span::{Span, Symbol}; @@ -78,6 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id) && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) + && !matches!(middle_trait_ref.substs.type_at(1).kind(), ty::Opaque(..)) { span_lint_and_then( cx, diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed index 125c9a69cd3f..72d635c2ccd6 100644 --- a/tests/ui/from_over_into.fixed +++ b/tests/ui/from_over_into.fixed @@ -1,5 +1,6 @@ // run-rustfix +#![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] #![allow(unused)] @@ -81,4 +82,10 @@ fn msrv_1_41() { } } +type Opaque = impl Sized; +struct IntoOpaque; +impl Into for IntoOpaque { + fn into(self) -> Opaque {} +} + fn main() {} diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs index 5aa127bfabe4..965f4d5d7859 100644 --- a/tests/ui/from_over_into.rs +++ b/tests/ui/from_over_into.rs @@ -1,5 +1,6 @@ // run-rustfix +#![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] #![allow(unused)] @@ -81,4 +82,10 @@ fn msrv_1_41() { } } +type Opaque = impl Sized; +struct IntoOpaque; +impl Into for IntoOpaque { + fn into(self) -> Opaque {} +} + fn main() {} diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr index a1764a5ea12a..3c4d011d6fb4 100644 --- a/tests/ui/from_over_into.stderr +++ b/tests/ui/from_over_into.stderr @@ -1,5 +1,5 @@ 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:9:1 + --> $DIR/from_over_into.rs:10:1 | LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL ~ StringWrapper(val) | 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:17:1 + --> $DIR/from_over_into.rs:18:1 | LL | impl Into for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL ~ SelfType(String::new()) | 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:32:1 + --> $DIR/from_over_into.rs:33:1 | LL | impl Into for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL ~ let _: X = val; | 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:44:1 + --> $DIR/from_over_into.rs:45:1 | LL | impl core::convert::Into for crate::ExplicitPaths { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL ~ val.0 | 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:77:5 + --> $DIR/from_over_into.rs:78:5 | LL | impl Into> for Vec { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^