From fb4e618c33789da31614d1d92b7c760df5db426b Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 8 Nov 2014 21:49:29 -0800 Subject: [PATCH 1/2] Fix upvars sometimes not being marked as used mutably Drill down the loan path for McDeclared references as well since it might lead to an upvar. Closes #18769 --- src/librustc/middle/borrowck/gather_loans/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 1a12828922c..7d893a0533a 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -395,10 +395,10 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => { self.tcx().used_mut_nodes.borrow_mut().insert(local_id); } - LpExtend(ref base, mc::McInherited, _) => { + LpExtend(ref base, mc::McInherited, _) | + LpExtend(ref base, mc::McDeclared, _) => { self.mark_loan_path_as_mutated(&**base); } - LpExtend(_, mc::McDeclared, _) | LpExtend(_, mc::McImmutable, _) => { // Nothing to do. } From c0a7d557dbea830ae581ecb3f77f08b7e4daad4a Mon Sep 17 00:00:00 2001 From: Brian Koropoff Date: Sat, 8 Nov 2014 21:51:02 -0800 Subject: [PATCH 2/2] Update test to cover #18769 --- src/test/run-pass/unboxed-closures-move-mutable.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/unboxed-closures-move-mutable.rs b/src/test/run-pass/unboxed-closures-move-mutable.rs index f7e1e46e54d..43a44eca2d0 100644 --- a/src/test/run-pass/unboxed-closures-move-mutable.rs +++ b/src/test/run-pass/unboxed-closures-move-mutable.rs @@ -14,7 +14,9 @@ // Test that mutating a mutable upvar in a capture-by-value unboxed // closure does not ice (issue #18238) and marks the upvar as used // mutably so we do not get a spurious warning about it not needing to -// be declared mutable (issue #18336). +// be declared mutable (issue #18336 and #18769) + +fn set(x: &mut uint) { *x = 42; } fn main() { { @@ -25,4 +27,12 @@ fn main() { let mut x = 0u; move |:| x += 1; } + { + let mut x = 0u; + move |&mut:| set(&mut x); + } + { + let mut x = 0u; + move |:| set(&mut x); + } }