Skip to content

Commit e7efe43

Browse files
committed
Auto merge of #12857 - WeiTheShinobi:non_canonical_impls, r=y21
fix: let non_canonical_impls skip proc marco Fixed #12788 Although the issue only mentions `NON_CANONICAL_CLONE_IMPL`, this fix will also affect `NON_CANONICAL_PARTIAL_ORD_IMPL` because I saw > Because of these unforeseeable or unstable behaviors, macro expansion should often not be regarded as a part of the stable API. on Clippy Documentation and these two lints are similar, so I think it might be good, not sure if it's right or not. --- changelog: `NON_CANONICAL_CLONE_IMPL`, `NON_CANONICAL_PARTIAL_ORD_IMPL` will skip proc marco now
2 parents 03654ba + 1038927 commit e7efe43

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

clippy_lints/src/non_canonical_impls.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
22
use clippy_utils::ty::implements_trait;
3-
use clippy_utils::{is_res_lang_ctor, last_path_segment, path_res, std_or_core};
3+
use clippy_utils::{is_from_proc_macro, is_res_lang_ctor, last_path_segment, path_res, std_or_core};
44
use rustc_errors::Applicability;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
7-
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_lint::{LateContext, LateLintPass, LintContext};
8+
use rustc_middle::lint::in_external_macro;
89
use rustc_middle::ty::EarlyBinder;
910
use rustc_session::declare_lint_pass;
1011
use rustc_span::sym;
@@ -111,7 +112,7 @@ declare_lint_pass!(NonCanonicalImpls => [NON_CANONICAL_CLONE_IMPL, NON_CANONICAL
111112

112113
impl LateLintPass<'_> for NonCanonicalImpls {
113114
#[expect(clippy::too_many_lines)]
114-
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
115+
fn check_impl_item<'tcx>(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'tcx>) {
115116
let Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id()) else {
116117
return;
117118
};
@@ -128,6 +129,9 @@ impl LateLintPass<'_> for NonCanonicalImpls {
128129
let ExprKind::Block(block, ..) = body.value.kind else {
129130
return;
130131
};
132+
if in_external_macro(cx.sess(), block.span) || is_from_proc_macro(cx, impl_item) {
133+
return;
134+
}
131135

132136
if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id)
133137
&& let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy)

tests/ui/auxiliary/proc_macro_derive.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,16 @@ pub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream {
169169
}
170170
}
171171
}
172+
173+
#[proc_macro_derive(NonCanonicalClone)]
174+
pub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream {
175+
quote! {
176+
struct NonCanonicalClone;
177+
impl Clone for NonCanonicalClone {
178+
fn clone(&self) -> Self {
179+
todo!()
180+
}
181+
}
182+
impl Copy for NonCanonicalClone {}
183+
}
184+
}

tests/ui/non_canonical_clone_impl.fixed

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
//@aux-build:proc_macro_derive.rs
12
#![allow(clippy::clone_on_copy, unused)]
23
#![allow(clippy::assigning_clones)]
34
#![no_main]
45

6+
extern crate proc_macros;
7+
use proc_macros::with_span;
8+
59
// lint
610

711
struct A(u32);
@@ -95,3 +99,19 @@ impl<A: Copy> Clone for Uwu<A> {
9599
}
96100

97101
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}
102+
103+
// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788
104+
#[derive(proc_macro_derive::NonCanonicalClone)]
105+
pub struct G;
106+
107+
with_span!(
108+
span
109+
110+
#[derive(Copy)]
111+
struct H;
112+
impl Clone for H {
113+
fn clone(&self) -> Self {
114+
todo!()
115+
}
116+
}
117+
);

tests/ui/non_canonical_clone_impl.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
//@aux-build:proc_macro_derive.rs
12
#![allow(clippy::clone_on_copy, unused)]
23
#![allow(clippy::assigning_clones)]
34
#![no_main]
45

6+
extern crate proc_macros;
7+
use proc_macros::with_span;
8+
59
// lint
610

711
struct A(u32);
@@ -105,3 +109,19 @@ impl<A: Copy> Clone for Uwu<A> {
105109
}
106110

107111
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}
112+
113+
// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788
114+
#[derive(proc_macro_derive::NonCanonicalClone)]
115+
pub struct G;
116+
117+
with_span!(
118+
span
119+
120+
#[derive(Copy)]
121+
struct H;
122+
impl Clone for H {
123+
fn clone(&self) -> Self {
124+
todo!()
125+
}
126+
}
127+
);

tests/ui/non_canonical_clone_impl.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: non-canonical implementation of `clone` on a `Copy` type
2-
--> tests/ui/non_canonical_clone_impl.rs:10:29
2+
--> tests/ui/non_canonical_clone_impl.rs:14:29
33
|
44
LL | fn clone(&self) -> Self {
55
| _____________________________^
@@ -11,7 +11,7 @@ LL | | }
1111
= help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`
1212

1313
error: unnecessary implementation of `clone_from` on a `Copy` type
14-
--> tests/ui/non_canonical_clone_impl.rs:14:5
14+
--> tests/ui/non_canonical_clone_impl.rs:18:5
1515
|
1616
LL | / fn clone_from(&mut self, source: &Self) {
1717
LL | | source.clone();
@@ -20,7 +20,7 @@ LL | | }
2020
| |_____^ help: remove it
2121

2222
error: non-canonical implementation of `clone` on a `Copy` type
23-
--> tests/ui/non_canonical_clone_impl.rs:81:29
23+
--> tests/ui/non_canonical_clone_impl.rs:85:29
2424
|
2525
LL | fn clone(&self) -> Self {
2626
| _____________________________^
@@ -29,7 +29,7 @@ LL | | }
2929
| |_____^ help: change this to: `{ *self }`
3030

3131
error: unnecessary implementation of `clone_from` on a `Copy` type
32-
--> tests/ui/non_canonical_clone_impl.rs:85:5
32+
--> tests/ui/non_canonical_clone_impl.rs:89:5
3333
|
3434
LL | / fn clone_from(&mut self, source: &Self) {
3535
LL | | source.clone();

0 commit comments

Comments
 (0)