Skip to content

Commit f4fdcc7

Browse files
Remove redundant logic to suggest as_ref
1 parent 8308806 commit f4fdcc7

File tree

6 files changed

+102
-56
lines changed

6 files changed

+102
-56
lines changed

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+7-46
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_middle::ty;
44
use rustc_mir_dataflow::move_paths::{
55
IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex,
66
};
7-
use rustc_span::{sym, Span};
7+
use rustc_span::Span;
88

99
use crate::diagnostics::UseSpans;
1010
use crate::prefixes::PrefixSet;
@@ -218,29 +218,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
218218

219219
fn report(&mut self, error: GroupedMoveError<'tcx>) {
220220
let (mut err, err_span) = {
221-
let (span, use_spans, original_path, kind, has_complex_bindings): (
222-
Span,
223-
Option<UseSpans<'tcx>>,
224-
Place<'tcx>,
225-
&IllegalMoveOriginKind<'_>,
226-
bool,
227-
) = match error {
228-
GroupedMoveError::MovesFromPlace {
229-
span,
230-
original_path,
231-
ref kind,
232-
ref binds_to,
233-
..
221+
let (span, use_spans, original_path, kind) = match error {
222+
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
223+
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
224+
(span, None, original_path, kind)
234225
}
235-
| GroupedMoveError::MovesFromValue {
236-
span,
237-
original_path,
238-
ref kind,
239-
ref binds_to,
240-
..
241-
} => (span, None, original_path, kind, !binds_to.is_empty()),
242226
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
243-
(use_spans.args_or_use(), Some(use_spans), original_path, kind, false)
227+
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
244228
}
245229
};
246230
debug!(
@@ -259,7 +243,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
259243
target_place,
260244
span,
261245
use_spans,
262-
has_complex_bindings,
263246
),
264247
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
265248
self.cannot_move_out_of_interior_of_drop(span, ty)
@@ -302,7 +285,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
302285
deref_target_place: Place<'tcx>,
303286
span: Span,
304287
use_spans: Option<UseSpans<'tcx>>,
305-
has_complex_bindings: bool,
306288
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
307289
// Inspect the type of the content behind the
308290
// borrow to provide feedback about why this
@@ -399,28 +381,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
399381
}
400382
}
401383
};
402-
let ty = move_place.ty(self.body, self.infcx.tcx).ty;
403-
let def_id = match *ty.kind() {
404-
ty::Adt(self_def, _) => self_def.did(),
405-
ty::Foreign(def_id)
406-
| ty::FnDef(def_id, _)
407-
| ty::Closure(def_id, _)
408-
| ty::Generator(def_id, ..)
409-
| ty::Opaque(def_id, _) => def_id,
410-
_ => return err,
411-
};
412-
let diag_name = self.infcx.tcx.get_diagnostic_name(def_id);
413-
if matches!(diag_name, Some(sym::Option | sym::Result))
414-
&& use_spans.map_or(true, |v| !v.for_closure())
415-
&& !has_complex_bindings
416-
{
417-
err.span_suggestion_verbose(
418-
span.shrink_to_hi(),
419-
&format!("consider borrowing the `{}`'s content", diag_name.unwrap()),
420-
".as_ref()",
421-
Applicability::MaybeIncorrect,
422-
);
423-
} else if let Some(use_spans) = use_spans {
384+
if let Some(use_spans) = use_spans {
424385
self.explain_captures(
425386
&mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
426387
);

src/test/ui/binop/binop-move-semantics.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,20 @@ LL | use_mut(n); use_imm(m);
6363
error[E0507]: cannot move out of `*m` which is behind a mutable reference
6464
--> $DIR/binop-move-semantics.rs:30:5
6565
|
66-
LL | *m
67-
| ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
66+
LL | *m
67+
| -^
68+
| |
69+
| _____move occurs because `*m` has type `T`, which does not implement the `Copy` trait
70+
| |
71+
LL | | +
72+
LL | | *n;
73+
| |______- `*m` moved due to usage in operator
74+
|
75+
note: calling this operator moves the left-hand side
76+
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
77+
|
78+
LL | fn add(self, rhs: Rhs) -> Self::Output;
79+
| ^^^^
6880

6981
error[E0507]: cannot move out of `*n` which is behind a shared reference
7082
--> $DIR/binop-move-semantics.rs:32:5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// This is not exactly right, yet.
2+
3+
// Ideally we should be suggesting `as_mut` for the first case,
4+
//and suggesting to change `as_ref` to `as_mut` in the second.
5+
6+
fn x(cb: &mut Option<&mut dyn FnMut()>) {
7+
cb.map(|cb| cb());
8+
//~^ ERROR cannot move out of `*cb` which is behind a mutable reference
9+
}
10+
11+
fn x2(cb: &mut Option<&mut dyn FnMut()>) {
12+
cb.as_ref().map(|cb| cb());
13+
//~^ ERROR cannot borrow `*cb` as mutable, as it is behind a `&` reference
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0507]: cannot move out of `*cb` which is behind a mutable reference
2+
--> $DIR/suggest-as-ref-on-mut-closure.rs:7:5
3+
|
4+
LL | cb.map(|cb| cb());
5+
| ^^^--------------
6+
| | |
7+
| | `*cb` moved due to this method call
8+
| move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
9+
|
10+
note: this function takes ownership of the receiver `self`, which moves `*cb`
11+
--> $SRC_DIR/core/src/option.rs:LL:COL
12+
|
13+
LL | pub const fn map<U, F>(self, f: F) -> Option<U>
14+
| ^^^^
15+
help: consider calling `.as_ref()` to borrow the type's contents
16+
|
17+
LL | cb.as_ref().map(|cb| cb());
18+
| +++++++++
19+
20+
error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference
21+
--> $DIR/suggest-as-ref-on-mut-closure.rs:12:26
22+
|
23+
LL | cb.as_ref().map(|cb| cb());
24+
| -- ^^ `cb` is a `&` reference, so the data it refers to cannot be borrowed as mutable
25+
| |
26+
| help: consider changing this to be a mutable reference: `&mut &mut dyn FnMut()`
27+
28+
error: aborting due to 2 previous errors
29+
30+
Some errors have detailed explanations: E0507, E0596.
31+
For more information about an error, try `rustc --explain E0507`.

src/test/ui/suggestions/option-content-move.stderr

+20-6
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,37 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
22
--> $DIR/option-content-move.rs:11:20
33
|
44
LL | if selection.1.unwrap().contains(selection.0) {
5-
| ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
5+
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
6+
| |
7+
| move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
68
|
7-
help: consider borrowing the `Option`'s content
9+
note: this function takes ownership of the receiver `self`, which moves `selection.1`
10+
--> $SRC_DIR/core/src/option.rs:LL:COL
11+
|
12+
LL | pub const fn unwrap(self) -> T {
13+
| ^^^^
14+
help: consider calling `.as_ref()` to borrow the type's contents
815
|
916
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
10-
| +++++++++
17+
| +++++++++
1118

1219
error[E0507]: cannot move out of `selection.1` which is behind a shared reference
1320
--> $DIR/option-content-move.rs:29:20
1421
|
1522
LL | if selection.1.unwrap().contains(selection.0) {
16-
| ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
23+
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
24+
| |
25+
| move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
26+
|
27+
note: this function takes ownership of the receiver `self`, which moves `selection.1`
28+
--> $SRC_DIR/core/src/result.rs:LL:COL
1729
|
18-
help: consider borrowing the `Result`'s content
30+
LL | pub fn unwrap(self) -> T
31+
| ^^^^
32+
help: consider calling `.as_ref()` to borrow the type's contents
1933
|
2034
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
21-
| +++++++++
35+
| +++++++++
2236

2337
error: aborting due to 2 previous errors
2438

src/test/ui/unop-move-semantics.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,25 @@ error[E0507]: cannot move out of `*m` which is behind a mutable reference
4646
--> $DIR/unop-move-semantics.rs:24:6
4747
|
4848
LL | !*m;
49-
| ^^ move occurs because `*m` has type `T`, which does not implement the `Copy` trait
49+
| -^^
50+
| ||
51+
| |move occurs because `*m` has type `T`, which does not implement the `Copy` trait
52+
| `*m` moved due to usage in operator
53+
|
54+
note: calling this operator moves the left-hand side
55+
--> $SRC_DIR/core/src/ops/bit.rs:LL:COL
56+
|
57+
LL | fn not(self) -> Self::Output;
58+
| ^^^^
5059

5160
error[E0507]: cannot move out of `*n` which is behind a shared reference
5261
--> $DIR/unop-move-semantics.rs:26:6
5362
|
5463
LL | !*n;
55-
| ^^ move occurs because `*n` has type `T`, which does not implement the `Copy` trait
64+
| -^^
65+
| ||
66+
| |move occurs because `*n` has type `T`, which does not implement the `Copy` trait
67+
| `*n` moved due to usage in operator
5668

5769
error: aborting due to 5 previous errors
5870

0 commit comments

Comments
 (0)