diff options
| author | Aman Arora <me@aman-arora.com> | 2020-12-15 23:00:19 -0500 |
|---|---|---|
| committer | Aman Arora <me@aman-arora.com> | 2021-01-29 15:37:42 -0500 |
| commit | 604cbdcfddb959cd1d7de2f9afa14a199561a428 (patch) | |
| tree | f711c27d880cc8c09ccfd6b7f7a5546b9c289539 /compiler | |
| parent | 0897db56098dd8e8355017f4364bc88f1e4f26c0 (diff) | |
| download | rust-604cbdcfddb959cd1d7de2f9afa14a199561a428.tar.gz rust-604cbdcfddb959cd1d7de2f9afa14a199561a428.zip | |
Fix unused 'mut' warning for capture's root variable
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_mir/src/borrow_check/mod.rs | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 1a771157e28..6e1e5c65aea 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -1369,13 +1369,38 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) { let propagate_closure_used_mut_place = |this: &mut Self, place: Place<'tcx>| { - if !place.projection.is_empty() { - if let Some(field) = this.is_upvar_field_projection(place.as_ref()) { + // We have three possiblities here: + // a. We are modifying something through a mut-ref + // b. We are modifying something that is local to our parent + // c. Current body is a nested clsoure, and we are modifying path starting from + // a Place captured by our parent closure. + + // Handle (c), the path being modified is exactly the path captured by our parent + if let Some(field) = this.is_upvar_field_projection(place.as_ref()) { + this.used_mut_upvars.push(field); + return; + } + + for (place_ref, proj) in place.iter_projections().rev() { + // Handle (a) + if proj == ProjectionElem::Deref { + match place_ref.ty(this.body(), this.infcx.tcx).ty.kind() { + // We aren't modifying a variable directly + ty::Ref(_, _, hir::Mutability::Mut) => return, + + _ => {} + } + } + + // Handle (c) + if let Some(field) = this.is_upvar_field_projection(place_ref) { this.used_mut_upvars.push(field); + return; } - } else { - this.used_mut.insert(place.local); } + + // Handle(b) + this.used_mut.insert(place.local); }; // This relies on the current way that by-value |
