Skip to content

Commit b49ff49

Browse files
committed
rustc_borrowck: Don't suggest changing closure param type not under user control
This changes output of a handful of tests more than the one added in the parent commit, but as far as I can tell, all removed suggestions were invalid.
1 parent 6ef6803 commit b49ff49

File tree

6 files changed

+25
-17
lines changed

6 files changed

+25
-17
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,26 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11981198
);
11991199
return;
12001200
}
1201+
1202+
// If `local` is a closure arg, and the type of the arg is not under
1203+
// local control, do not suggest to change its type.
1204+
if self.body.local_kind(local) == LocalKind::Arg
1205+
&& let InstanceKind::Item(def_id) = self.body.source.instance
1206+
&& let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) =
1207+
self.infcx.tcx.hir_get_if_local(def_id)
1208+
&& let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind
1209+
&& let Node::Expr(expr) = self.infcx.tcx.parent_hir_node(*hir_id)
1210+
&& let ExprKind::MethodCall(path_segment, _, _, _) = expr.kind
1211+
&& self
1212+
.infcx
1213+
.tcx
1214+
.typeck(path_segment.hir_id.owner.def_id)
1215+
.type_dependent_def_id(expr.hir_id)
1216+
.is_some_and(|def_id| !def_id.is_local())
1217+
{
1218+
return;
1219+
}
1220+
12011221
let decl_span = local_decl.source_info.span;
12021222

12031223
let (amp_mut_sugg, local_var_ty_info) = match *local_decl.local_info() {

tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0596]: cannot borrow `**layer` as mutable, as it is behind a `&` referenc
22
--> $DIR/issue-115259-suggest-iter-mut.rs:15:65
33
|
44
LL | self.layers.iter().fold(0, |result, mut layer| result + layer.process())
5-
| --------- ^^^^^ `layer` is a `&` reference, so it cannot be borrowed as mutable
6-
| |
7-
| consider changing this binding's type to be: `&mut Box<dyn Layer>`
5+
| ^^^^^ `layer` is a `&` reference, so it cannot be borrowed as mutable
86
|
97
help: you may want to use `iter_mut` here
108
|

tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0596]: cannot borrow `*container` as mutable, as it is behind a `&` refer
22
--> $DIR/issue-62387-suggest-iter-mut-2.rs:30:45
33
|
44
LL | vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>();
5-
| --------- ^^^^^^^^^ `container` is a `&` reference, so it cannot be borrowed as mutable
6-
| |
7-
| consider changing this binding's type to be: `&mut Container`
5+
| ^^^^^^^^^ `container` is a `&` reference, so it cannot be borrowed as mutable
86
|
97
help: you may want to use `iter_mut` here
108
|

tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
22
--> $DIR/issue-62387-suggest-iter-mut.rs:18:27
33
|
44
LL | v.iter().for_each(|a| a.double());
5-
| - ^ `a` is a `&` reference, so it cannot be borrowed as mutable
6-
| |
7-
| consider changing this binding's type to be: `&mut A`
5+
| ^ `a` is a `&` reference, so it cannot be borrowed as mutable
86
|
97
help: you may want to use `iter_mut` here
108
|
@@ -15,9 +13,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
1513
--> $DIR/issue-62387-suggest-iter-mut.rs:25:39
1614
|
1715
LL | v.iter().rev().rev().for_each(|a| a.double());
18-
| - ^ `a` is a `&` reference, so it cannot be borrowed as mutable
19-
| |
20-
| consider changing this binding's type to be: `&mut A`
16+
| ^ `a` is a `&` reference, so it cannot be borrowed as mutable
2117
|
2218
help: you may want to use `iter_mut` here
2319
|

tests/ui/borrowck/option-inspect-mutation.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
error[E0594]: cannot assign to `some_struct.field`, which is behind a `&` reference
22
--> $DIR/option-inspect-mutation.rs:10:9
33
|
4-
LL | some_struct.as_mut().inspect(|some_struct| {
5-
| ----------- consider changing this binding's type to be: `&mut &mut Struct`
64
LL | some_struct.field *= 10;
75
| ^^^^^^^^^^^^^^^^^^^^^^^ `some_struct` is a `&` reference, so it cannot be written to
86

tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ error[E0596]: cannot borrow `*cb` as mutable, as it is behind a `&` reference
1818
--> $DIR/suggest-as-ref-on-mut-closure.rs:12:26
1919
|
2020
LL | cb.as_ref().map(|cb| cb());
21-
| -- ^^ `cb` is a `&` reference, so it cannot be borrowed as mutable
22-
| |
23-
| consider changing this binding's type to be: `&mut &mut dyn FnMut()`
21+
| ^^ `cb` is a `&` reference, so it cannot be borrowed as mutable
2422

2523
error: aborting due to 2 previous errors
2624

0 commit comments

Comments
 (0)