Skip to content

Commit

Permalink
Rollup merge of #109680 - clubby789:array-subslice-2229, r=davidtwco
Browse files Browse the repository at this point in the history
Fix subslice capture in closure

Fixes #109298 by refining captures in the same way for Subslices and Indexes. The comment `// we never capture this` seems to have been inaccurate, as changing it to an assert causes many test failures

`@rustbot` label +A-closures
  • Loading branch information
GuillaumeGomez committed Mar 31, 2023
2 parents 6c93c63 + f995003 commit 45fcb6f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
5 changes: 2 additions & 3 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1893,14 +1893,13 @@ fn restrict_capture_precision(

for (i, proj) in place.projections.iter().enumerate() {
match proj.kind {
ProjectionKind::Index => {
// Arrays are completely captured, so we drop Index projections
ProjectionKind::Index | ProjectionKind::Subslice => {
// Arrays are completely captured, so we drop Index and Subslice projections
truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i);
return (place, curr_mode);
}
ProjectionKind::Deref => {}
ProjectionKind::Field(..) => {} // ignore
ProjectionKind::Subslice => {} // We never capture this
}
}

Expand Down
13 changes: 13 additions & 0 deletions tests/ui/closures/2229_closure_analysis/array_subslice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// regression test for #109298
// edition: 2021

pub fn subslice_array(x: [u8; 3]) {
let f = || {
let [_x @ ..] = x;
let [ref y, ref mut z @ ..] = x; //~ ERROR cannot borrow `x[..]` as mutable
};

f(); //~ ERROR cannot borrow `f` as mutable
}

fn main() {}
26 changes: 26 additions & 0 deletions tests/ui/closures/2229_closure_analysis/array_subslice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error[E0596]: cannot borrow `x[..]` as mutable, as `x` is not declared as mutable
--> $DIR/array_subslice.rs:7:21
|
LL | pub fn subslice_array(x: [u8; 3]) {
| - help: consider changing this to be mutable: `mut x`
...
LL | let [ref y, ref mut z @ ..] = x;
| ^^^^^^^^^ cannot borrow as mutable

error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
--> $DIR/array_subslice.rs:10:5
|
LL | let [ref y, ref mut z @ ..] = x;
| - calling `f` requires mutable binding due to mutable borrow of `x`
...
LL | f();
| ^ cannot borrow as mutable
|
help: consider changing this to be mutable
|
LL | let mut f = || {
| +++

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0596`.

0 comments on commit 45fcb6f

Please sign in to comment.