Skip to content

Commit 010bca6

Browse files
authored
Rollup merge of rust-lang#153258 - lapla-cogito:issue_153126, r=Kivooeo
diag: Suppress `.clone()` suggestion inside derive macro expansions Derives on a packed struct with non-Copy fields generate moves whose spans point back at the original field type definitions. `suggest_cloning_inner()` then proposes inserting `.clone()` at those locations, producing nonsensical output like `String.clone()` in the struct definition. close rust-lang#153126
2 parents 70287b9 + 3cecc8d commit 010bca6

4 files changed

Lines changed: 40 additions & 37 deletions

File tree

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_middle::ty::{
2828
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
2929
use rustc_span::def_id::{DefId, LocalDefId};
3030
use rustc_span::hygiene::DesugaringKind;
31-
use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
31+
use rustc_span::{BytePos, ExpnKind, Ident, MacroKind, Span, Symbol, kw, sym};
3232
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
3333
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
3434
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
@@ -1438,6 +1438,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
14381438
expr: &hir::Expr<'_>,
14391439
) -> bool {
14401440
let tcx = self.infcx.tcx;
1441+
1442+
// Don't suggest `.clone()` in a derive macro expansion.
1443+
if let ExpnKind::Macro(MacroKind::Derive, _) = self.body.span.ctxt().outer_expn_data().kind
1444+
{
1445+
return false;
1446+
}
14411447
if let Some(_) = self.clone_on_reference(expr) {
14421448
// Avoid redundant clone suggestion already suggested in `explain_captures`.
14431449
// See `tests/ui/moves/needs-clone-through-deref.rs`

tests/ui/derives/deriving-with-repr-packed-move-errors.stderr

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ LL | struct StructA(String);
77
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
88
|
99
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
10-
help: consider cloning the value if the performance cost is acceptable
11-
|
12-
LL | struct StructA(String.clone());
13-
| ++++++++
1410

1511
error[E0507]: cannot move out of a shared reference
1612
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -21,10 +17,6 @@ LL | struct StructA(String);
2117
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
2218
|
2319
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
24-
help: consider cloning the value if the performance cost is acceptable
25-
|
26-
LL | struct StructA(String.clone());
27-
| ++++++++
2820

2921
error[E0507]: cannot move out of a shared reference
3022
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -36,10 +28,6 @@ LL | struct StructA(String);
3628
|
3729
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
3830
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
39-
help: consider cloning the value if the performance cost is acceptable
40-
|
41-
LL | struct StructA(String.clone());
42-
| ++++++++
4331

4432
error[E0507]: cannot move out of a shared reference
4533
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -50,10 +38,6 @@ LL | struct StructA(String);
5038
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
5139
|
5240
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
53-
help: consider cloning the value if the performance cost is acceptable
54-
|
55-
LL | struct StructA(String.clone());
56-
| ++++++++
5741

5842
error[E0507]: cannot move out of a shared reference
5943
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -65,10 +49,6 @@ LL | struct StructA(String);
6549
|
6650
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
6751
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
68-
help: consider cloning the value if the performance cost is acceptable
69-
|
70-
LL | struct StructA(String.clone());
71-
| ++++++++
7252

7353
error[E0507]: cannot move out of a shared reference
7454
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -79,10 +59,6 @@ LL | struct StructA(String);
7959
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
8060
|
8161
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
82-
help: consider cloning the value if the performance cost is acceptable
83-
|
84-
LL | struct StructA(String.clone());
85-
| ++++++++
8662

8763
error[E0507]: cannot move out of a shared reference
8864
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -94,10 +70,6 @@ LL | struct StructA(String);
9470
|
9571
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
9672
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
97-
help: consider cloning the value if the performance cost is acceptable
98-
|
99-
LL | struct StructA(String.clone());
100-
| ++++++++
10173

10274
error[E0507]: cannot move out of a shared reference
10375
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -108,10 +80,6 @@ LL | struct StructA(String);
10880
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
10981
|
11082
= note: `#[derive(Hash)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
111-
help: consider cloning the value if the performance cost is acceptable
112-
|
113-
LL | struct StructA(String.clone());
114-
| ++++++++
11583

11684
error[E0507]: cannot move out of a shared reference
11785
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -122,10 +90,6 @@ LL | struct StructA(String);
12290
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
12391
|
12492
= note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
125-
help: consider cloning the value if the performance cost is acceptable
126-
|
127-
LL | struct StructA(String.clone());
128-
| ++++++++
12993

13094
error[E0507]: cannot move out of `self` which is behind a shared reference
13195
--> $DIR/deriving-with-repr-packed-move-errors.rs:28:9
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Test for https://github.com/rust-lang/rust/issues/153126
2+
3+
#[repr(packed, C)]
4+
#[derive(PartialEq)]
5+
struct Thing(u8, String);
6+
//~^ ERROR cannot move out of a shared reference
7+
//~| ERROR cannot move out of a shared reference
8+
9+
fn main() {}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0507]: cannot move out of a shared reference
2+
--> $DIR/deriving-with-repr-packed-no-clone-suggestion.rs:5:18
3+
|
4+
LL | #[derive(PartialEq)]
5+
| --------- in this derive macro expansion
6+
LL | struct Thing(u8, String);
7+
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
8+
|
9+
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
10+
11+
error[E0507]: cannot move out of a shared reference
12+
--> $DIR/deriving-with-repr-packed-no-clone-suggestion.rs:5:18
13+
|
14+
LL | #[derive(PartialEq)]
15+
| --------- in this derive macro expansion
16+
LL | struct Thing(u8, String);
17+
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
18+
|
19+
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
20+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0507`.

0 commit comments

Comments
 (0)