Skip to content

Commit 51c89a4

Browse files
committed
Auto merge of #12264 - y21:issue12263, r=Jarcho
[`to_string_trait_impl`]: avoid linting if the impl is a specialization Fixes #12263 Oh well... #12122 (comment) 🙃 changelog: [`to_string_trait_impl`]: avoid linting if the impl is a specialization
2 parents e67b7e0 + b3b9919 commit 51c89a4

File tree

3 files changed

+61
-2
lines changed

3 files changed

+61
-2
lines changed

clippy_lints/src/to_string_trait_impl.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_help;
2+
use clippy_utils::ty::implements_trait;
23
use rustc_hir::{Impl, Item, ItemKind};
34
use rustc_lint::{LateContext, LateLintPass};
45
use rustc_session::declare_lint_pass;
@@ -53,6 +54,8 @@ impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {
5354
}) = it.kind
5455
&& let Some(trait_did) = trait_ref.trait_def_id()
5556
&& cx.tcx.is_diagnostic_item(sym::ToString, trait_did)
57+
&& let Some(display_did) = cx.tcx.get_diagnostic_item(sym::Display)
58+
&& !implements_trait(cx, cx.tcx.type_of(it.owner_id).instantiate_identity(), display_did, &[])
5659
{
5760
span_lint_and_help(
5861
cx,

tests/ui/to_string_trait_impl.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![warn(clippy::to_string_trait_impl)]
2+
#![feature(min_specialization)]
23

34
use std::fmt::{self, Display};
45

@@ -29,3 +30,46 @@ impl Bar {
2930
String::from("Bar")
3031
}
3132
}
33+
34+
mod issue12263 {
35+
pub struct MyStringWrapper<'a>(&'a str);
36+
37+
impl std::fmt::Display for MyStringWrapper<'_> {
38+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39+
self.0.fmt(f)
40+
}
41+
}
42+
43+
impl ToString for MyStringWrapper<'_> {
44+
fn to_string(&self) -> String {
45+
self.0.to_string()
46+
}
47+
}
48+
49+
pub struct S<T>(T);
50+
impl std::fmt::Display for S<String> {
51+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52+
todo!()
53+
}
54+
}
55+
// no specialization if the generics differ, so lint
56+
impl ToString for S<i32> {
57+
fn to_string(&self) -> String {
58+
todo!()
59+
}
60+
}
61+
62+
pub struct S2<T>(T);
63+
impl std::fmt::Display for S2<String> {
64+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65+
todo!()
66+
}
67+
}
68+
69+
// also specialization if the generics don't differ
70+
impl ToString for S2<String> {
71+
fn to_string(&self) -> String {
72+
todo!()
73+
}
74+
}
75+
}

tests/ui/to_string_trait_impl.stderr

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: direct implementation of `ToString`
2-
--> $DIR/to_string_trait_impl.rs:10:1
2+
--> $DIR/to_string_trait_impl.rs:11:1
33
|
44
LL | / impl ToString for Point {
55
LL | | fn to_string(&self) -> String {
@@ -12,5 +12,17 @@ LL | | }
1212
= note: `-D clippy::to-string-trait-impl` implied by `-D warnings`
1313
= help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]`
1414

15-
error: aborting due to 1 previous error
15+
error: direct implementation of `ToString`
16+
--> $DIR/to_string_trait_impl.rs:56:5
17+
|
18+
LL | / impl ToString for S<i32> {
19+
LL | | fn to_string(&self) -> String {
20+
LL | | todo!()
21+
LL | | }
22+
LL | | }
23+
| |_____^
24+
|
25+
= help: prefer implementing `Display` instead
26+
27+
error: aborting due to 2 previous errors
1628

0 commit comments

Comments
 (0)