about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-16 12:34:40 -0700
committerbors <bors@rust-lang.org>2013-05-16 12:34:40 -0700
commitc8159b3e351f3840f4097761c8404e064869ff2a (patch)
treee45c974fe333d599fbd9d86b0e11ed593e0a1b57
parentcf8341fc9e1c18c973a6744ecd7ebb97adbd3025 (diff)
parent63d878f36b2630ac0fcb4bcaa123b135126b091a (diff)
downloadrust-c8159b3e351f3840f4097761c8404e064869ff2a.tar.gz
rust-c8159b3e351f3840f4097761c8404e064869ff2a.zip
auto merge of #6473 : nikomatsakis/rust/issue-5967-rvalue-immutability, r=pcwalton
Simpler version of PR #5974 based on new borrowck.
-rw-r--r--src/librustc/middle/borrowck/gather_loans/lifetime.rs15
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/test/compile-fail/borrowck-rvalues-mutable-bad.rs38
-rw-r--r--src/test/run-pass/borrowck-rvalues-mutable.rs30
4 files changed, 83 insertions, 2 deletions
diff --git a/src/librustc/middle/borrowck/gather_loans/lifetime.rs b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
index 330d60a59d3..e377bebcc26 100644
--- a/src/librustc/middle/borrowck/gather_loans/lifetime.rs
+++ b/src/librustc/middle/borrowck/gather_loans/lifetime.rs
@@ -93,7 +93,7 @@ impl GuaranteeLifetimeContext {
                 let omit_root = (
                     ptr_mutbl == m_imm &&
                     self.bccx.is_subregion_of(self.loan_region, base_scope) &&
-                    base.mutbl.is_immutable() &&
+                    self.is_rvalue_or_immutable(base) &&
                     !self.is_moved(base)
                 );
 
@@ -168,6 +168,19 @@ impl GuaranteeLifetimeContext {
         }
     }
 
+    fn is_rvalue_or_immutable(&self,
+                              cmt: mc::cmt) -> bool {
+        //! We can omit the root on an `@T` value if the location
+        //! that holds the box is either (1) an rvalue, in which case
+        //! it is in a non-user-accessible temporary, or (2) an immutable
+        //! lvalue.
+
+        cmt.mutbl.is_immutable() || match cmt.guarantor().cat {
+            mc::cat_rvalue => true,
+            _ => false
+        }
+    }
+
     fn check_root(&self,
                   cmt_deref: mc::cmt,
                   cmt_base: mc::cmt,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 95ed7fe8efc..91c0b8e61cc 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -551,7 +551,7 @@ pub impl mem_categorization_ctxt {
             id:elt.id(),
             span:elt.span(),
             cat:cat_rvalue,
-            mutbl:McImmutable,
+            mutbl:McDeclared,
             ty:expr_ty
         }
     }
diff --git a/src/test/compile-fail/borrowck-rvalues-mutable-bad.rs b/src/test/compile-fail/borrowck-rvalues-mutable-bad.rs
new file mode 100644
index 00000000000..10bef907a28
--- /dev/null
+++ b/src/test/compile-fail/borrowck-rvalues-mutable-bad.rs
@@ -0,0 +1,38 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Tests that rvalue lifetimes is limited to the enclosing trans
+// cleanup scope. It is unclear that this is the correct lifetime for
+// rvalues, but that's what it is right now.
+
+struct Counter {
+    value: uint
+}
+
+impl Counter {
+    fn new(v: uint) -> Counter {
+        Counter {value: v}
+    }
+
+    fn inc<'a>(&'a mut self) -> &'a mut Counter {
+        self.value += 1;
+        self
+    }
+
+    fn get(&self) -> uint {
+        self.value
+    }
+}
+
+pub fn main() {
+    let v = Counter::new(22).inc().inc().get();
+    //~^ ERROR borrowed value does not live long enough
+    assert_eq!(v, 24);;
+}
diff --git a/src/test/run-pass/borrowck-rvalues-mutable.rs b/src/test/run-pass/borrowck-rvalues-mutable.rs
new file mode 100644
index 00000000000..cf5a9341c9d
--- /dev/null
+++ b/src/test/run-pass/borrowck-rvalues-mutable.rs
@@ -0,0 +1,30 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Counter {
+    value: uint
+}
+
+impl Counter {
+    fn new(v: uint) -> Counter {
+        Counter {value: v}
+    }
+
+    fn get_and_inc(&mut self) -> uint {
+        let v = self.value;
+        self.value += 1;
+        v
+    }
+}
+
+pub fn main() {
+    let v = Counter::new(22).get_and_inc();
+    assert_eq!(v, 22);
+}