[inherent_to_string]: Don't lint unsafe or extern fns

This commit is contained in:
Catherine Flores 2023-07-21 06:45:30 -05:00
parent 7c5095c502
commit f3f7f63c16
3 changed files with 44 additions and 27 deletions

View file

@ -1,11 +1,11 @@
use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::{implements_trait, is_type_lang_item}; use clippy_utils::ty::{implements_trait, is_type_lang_item};
use clippy_utils::{return_ty, trait_ref_of_method}; use clippy_utils::{return_ty, trait_ref_of_method};
use if_chain::if_chain; use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem, Unsafety};
use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym; use rustc_span::sym;
use rustc_target::spec::abi::Abi;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@ -95,24 +95,23 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
return; return;
} }
if_chain! { // Check if item is a method called `to_string` and has a parameter 'self'
// Check if item is a method, called to_string and has a parameter 'self' if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
if let ImplItemKind::Fn(ref signature, _) = impl_item.kind; // #11201
if impl_item.ident.name == sym::to_string; && let header = signature.header
let decl = &signature.decl; && header.unsafety == Unsafety::Normal
if decl.implicit_self.has_implicit_self(); && header.abi == Abi::Rust
if decl.inputs.len() == 1; && impl_item.ident.name == sym::to_string
if impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. })); && let decl = signature.decl
&& decl.implicit_self.has_implicit_self()
&& decl.inputs.len() == 1
&& impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
// Check if return type is String // Check if return type is String
if is_type_lang_item(cx, return_ty(cx, impl_item.owner_id), LangItem::String); && is_type_lang_item(cx, return_ty(cx, impl_item.owner_id), LangItem::String)
// Filters instances of to_string which are required by a trait // Filters instances of to_string which are required by a trait
if trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none(); && trait_ref_of_method(cx, impl_item.owner_id.def_id).is_none()
{
then { show_lint(cx, impl_item);
show_lint(cx, impl_item);
}
} }
} }
} }

View file

@ -1,5 +1,4 @@
#![warn(clippy::inherent_to_string)] #![allow(improper_ctypes_definitions)]
#![deny(clippy::inherent_to_string_shadow_display)]
use std::fmt; use std::fmt;
@ -14,6 +13,9 @@ struct D;
struct E; struct E;
struct F; struct F;
struct G; struct G;
struct H;
struct I;
struct J;
impl A { impl A {
// Should be detected; emit warning // Should be detected; emit warning
@ -80,6 +82,26 @@ impl G {
} }
} }
// Issue #11201
impl H {
unsafe fn to_string(&self) -> String {
"G.to_string()".to_string()
}
}
impl I {
extern "C" fn to_string(&self) -> String {
"G.to_string()".to_string()
}
}
impl J {
unsafe extern "C" fn to_string(&self) -> String {
"G.to_string()".to_string()
}
}
fn main() { fn main() {
let a = A; let a = A;
a.to_string(); a.to_string();

View file

@ -1,5 +1,5 @@
error: implementation of inherent method `to_string(&self) -> String` for type `A` error: implementation of inherent method `to_string(&self) -> String` for type `A`
--> $DIR/inherent_to_string.rs:20:5 --> $DIR/inherent_to_string.rs:22:5
| |
LL | / fn to_string(&self) -> String { LL | / fn to_string(&self) -> String {
LL | | "A.to_string()".to_string() LL | | "A.to_string()".to_string()
@ -10,7 +10,7 @@ LL | | }
= note: `-D clippy::inherent-to-string` implied by `-D warnings` = note: `-D clippy::inherent-to-string` implied by `-D warnings`
error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display` error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`
--> $DIR/inherent_to_string.rs:44:5 --> $DIR/inherent_to_string.rs:46:5
| |
LL | / fn to_string(&self) -> String { LL | / fn to_string(&self) -> String {
LL | | "C.to_string()".to_string() LL | | "C.to_string()".to_string()
@ -18,11 +18,7 @@ LL | | }
| |_____^ | |_____^
| |
= help: remove the inherent method from type `C` = help: remove the inherent method from type `C`
note: the lint level is defined here = note: `#[deny(clippy::inherent_to_string_shadow_display)]` on by default
--> $DIR/inherent_to_string.rs:2:9
|
LL | #![deny(clippy::inherent_to_string_shadow_display)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors