From f995003ec5053c85efca895d0506392d3be88286 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Mar 2023 22:23:10 +0100 Subject: [PATCH] Fix subslice capture in closure --- compiler/rustc_hir_typeck/src/upvar.rs | 5 ++-- .../2229_closure_analysis/array_subslice.rs | 13 ++++++++++ .../array_subslice.stderr | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/ui/closures/2229_closure_analysis/array_subslice.rs create mode 100644 tests/ui/closures/2229_closure_analysis/array_subslice.stderr diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 8fe5a3cc78911..61c4535365a52 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -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 } } diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.rs b/tests/ui/closures/2229_closure_analysis/array_subslice.rs new file mode 100644 index 0000000000000..5f244ea89365d --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/array_subslice.rs @@ -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() {} diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr new file mode 100644 index 0000000000000..888c60d5e91fb --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr @@ -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`.