Skip to content

Commit 1712ab2

Browse files
committed
auto merge of #16253 : luqmana/rust/muv, r=nikomatsakis
Fixes #11958.
2 parents 87134c7 + f765759 commit 1712ab2

File tree

5 files changed

+91
-28
lines changed

5 files changed

+91
-28
lines changed

src/librustc/middle/borrowck/check_loans.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -764,18 +764,17 @@ impl<'a> CheckLoanCtxt<'a> {
764764
return;
765765

766766
fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
767-
cmt: mc::cmt) {
767+
mut cmt: mc::cmt) {
768768
//! If the mutability of the `cmt` being written is inherited
769769
//! from a local variable, liveness will
770770
//! not have been able to detect that this variable's mutability
771771
//! is important, so we must add the variable to the
772772
//! `used_mut_nodes` table here.
773773
774-
let mut cmt = cmt;
775774
loop {
776-
debug!("mark_writes_through_upvars_as_used_mut(cmt={})",
777-
cmt.repr(this.tcx()));
775+
debug!("mark_variable_as_used_mut(cmt={})", cmt.repr(this.tcx()));
778776
match cmt.cat.clone() {
777+
mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id, .. }) |
779778
mc::cat_local(id) | mc::cat_arg(id) => {
780779
this.tcx().used_mut_nodes.borrow_mut().insert(id);
781780
return;
@@ -792,7 +791,6 @@ impl<'a> CheckLoanCtxt<'a> {
792791

793792
mc::cat_rvalue(..) |
794793
mc::cat_static_item |
795-
mc::cat_copied_upvar(..) |
796794
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
797795
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
798796
mc::cat_deref(_, _, mc::Implicit(..)) => {

src/librustc/middle/mem_categorization.rs

+34-23
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,29 @@ impl MutabilityCategory {
306306
}
307307
}
308308

309+
fn from_def(def: &def::Def) -> MutabilityCategory {
310+
match *def {
311+
def::DefFn(..) | def::DefStaticMethod(..) | def::DefSelfTy(..) |
312+
def::DefMod(..) | def::DefForeignMod(..) | def::DefVariant(..) |
313+
def::DefTy(..) | def::DefTrait(..) | def::DefPrimTy(..) |
314+
def::DefTyParam(..) | def::DefUse(..) | def::DefStruct(..) |
315+
def::DefTyParamBinder(..) | def::DefRegion(..) | def::DefLabel(..) |
316+
def::DefMethod(..) => fail!("no MutabilityCategory for def: {}", *def),
317+
318+
def::DefStatic(_, false) => McImmutable,
319+
def::DefStatic(_, true) => McDeclared,
320+
321+
def::DefArg(_, binding_mode) |
322+
def::DefBinding(_, binding_mode) |
323+
def::DefLocal(_, binding_mode) => match binding_mode {
324+
ast::BindByValue(ast::MutMutable) => McDeclared,
325+
_ => McImmutable
326+
},
327+
328+
def::DefUpvar(_, def, _, _) => MutabilityCategory::from_def(&*def)
329+
}
330+
}
331+
309332
pub fn inherit(&self) -> MutabilityCategory {
310333
match *self {
311334
McImmutable => McImmutable,
@@ -503,8 +526,8 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
503526
def::DefStaticMethod(..) => {
504527
Ok(self.cat_rvalue_node(id, span, expr_ty))
505528
}
506-
def::DefMod(_) | def::DefForeignMod(_) | def::DefStatic(_, false) |
507-
def::DefUse(_) | def::DefTrait(_) | def::DefTy(_) | def::DefPrimTy(_) |
529+
def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
530+
def::DefTrait(_) | def::DefTy(_) | def::DefPrimTy(_) |
508531
def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
509532
def::DefLabel(_) | def::DefSelfTy(..) | def::DefMethod(..) => {
510533
Ok(Rc::new(cmt_ {
@@ -516,30 +539,25 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
516539
}))
517540
}
518541

519-
def::DefStatic(_, true) => {
542+
def::DefStatic(_, _) => {
520543
Ok(Rc::new(cmt_ {
521544
id:id,
522545
span:span,
523546
cat:cat_static_item,
524-
mutbl: McDeclared,
547+
mutbl: MutabilityCategory::from_def(&def),
525548
ty:expr_ty
526549
}))
527550
}
528551

529-
def::DefArg(vid, binding_mode) => {
552+
def::DefArg(vid, _) => {
530553
// Idea: make this could be rewritten to model by-ref
531554
// stuff as `&const` and `&mut`?
532555

533-
// m: mutability of the argument
534-
let m = match binding_mode {
535-
ast::BindByValue(ast::MutMutable) => McDeclared,
536-
_ => McImmutable
537-
};
538556
Ok(Rc::new(cmt_ {
539557
id: id,
540558
span: span,
541559
cat: cat_arg(vid),
542-
mutbl: m,
560+
mutbl: MutabilityCategory::from_def(&def),
543561
ty:expr_ty
544562
}))
545563
}
@@ -564,7 +582,6 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
564582
if var_is_refd {
565583
self.cat_upvar(id, span, var_id, fn_node_id)
566584
} else {
567-
// FIXME #2152 allow mutation of moved upvars
568585
Ok(Rc::new(cmt_ {
569586
id:id,
570587
span:span,
@@ -573,13 +590,12 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
573590
onceness: closure_ty.onceness,
574591
capturing_proc: fn_node_id,
575592
}),
576-
mutbl:McImmutable,
593+
mutbl: MutabilityCategory::from_def(&def),
577594
ty:expr_ty
578595
}))
579596
}
580597
}
581598
ty::ty_unboxed_closure(_) => {
582-
// FIXME #2152 allow mutation of moved upvars
583599
Ok(Rc::new(cmt_ {
584600
id: id,
585601
span: span,
@@ -588,7 +604,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
588604
onceness: ast::Many,
589605
capturing_proc: fn_node_id,
590606
}),
591-
mutbl: McImmutable,
607+
mutbl: MutabilityCategory::from_def(&def),
592608
ty: expr_ty
593609
}))
594610
}
@@ -602,19 +618,14 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
602618
}
603619
}
604620

605-
def::DefLocal(vid, binding_mode) |
606-
def::DefBinding(vid, binding_mode) => {
621+
def::DefLocal(vid, _) |
622+
def::DefBinding(vid, _) => {
607623
// by-value/by-ref bindings are local variables
608-
let m = match binding_mode {
609-
ast::BindByValue(ast::MutMutable) => McDeclared,
610-
_ => McImmutable
611-
};
612-
613624
Ok(Rc::new(cmt_ {
614625
id: id,
615626
span: span,
616627
cat: cat_local(vid),
617-
mutbl: m,
628+
mutbl: MutabilityCategory::from_def(&def),
618629
ty: expr_ty
619630
}))
620631
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let x = 1i;
13+
proc() { x = 2; };
14+
//~^ ERROR: cannot assign to immutable captured outer variable in a proc `x`
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![forbid(unused_mut)]
12+
13+
fn main() {
14+
let mut x = 1i;
15+
//~^ ERROR: variable does not need to be mutable
16+
proc() { println!("{}", x); };
17+
}

src/test/run-pass/issue-11958.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![forbid(warnings)]
12+
13+
// Pretty printing tests complain about `use std::predule::*`
14+
#![allow(unused_imports)]
15+
16+
// We shouldn't need to rebind a moved upvar as mut if it's already
17+
// marked as mut
18+
19+
pub fn main() {
20+
let mut x = 1i;
21+
proc() { x = 2; };
22+
}

0 commit comments

Comments
 (0)