about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@mozilla.com>2014-07-30 13:36:21 -0700
committerCameron Zwarich <zwarich@mozilla.com>2014-07-30 13:36:21 -0700
commit8c4dbf3d4750feb47aec09b3f2df848e8f7b5469 (patch)
treef06bbdc1390983fe010e04940acff86f9a276d38
parent8da03d9771bc827eae713d16bca7bec4c5fe6a10 (diff)
downloadrust-8c4dbf3d4750feb47aec09b3f2df848e8f7b5469.tar.gz
rust-8c4dbf3d4750feb47aec09b3f2df848e8f7b5469.zip
Add two helper functions for dealing with OwnedPtr paths
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index b570cb43f16..fd867393469 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -28,6 +28,57 @@ use util::ppaux::Repr;
 
 use std::rc::Rc;
 
+// FIXME (#16118): These functions are intended to allow the borrow checker to
+// be less precise in its handling of Box while still allowing moves out of a
+// Box. They should be removed when OwnedPtr is removed from LoanPath.
+
+fn owned_ptr_base_path<'a>(loan_path: &'a LoanPath) -> &'a LoanPath {
+    //! Returns the base of the leftmost dereference of an OwnedPtr in
+    //! `loan_path`. If there is no dereference of an OwnedPtr in `loan_path`,
+    //! then it just returns `loan_path` itself.
+
+    return match owned_ptr_base_path_helper(loan_path) {
+        Some(new_loan_path) => new_loan_path,
+        None => loan_path.clone()
+    };
+
+    fn owned_ptr_base_path_helper<'a>(loan_path: &'a LoanPath) -> Option<&'a LoanPath> {
+        match *loan_path {
+            LpVar(_) | LpUpvar(_) => None,
+            LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => {
+                match owned_ptr_base_path_helper(&**lp_base) {
+                    v @ Some(_) => v,
+                    None => Some(&**lp_base)
+                }
+            }
+            LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(&**lp_base)
+        }
+    }
+}
+
+fn owned_ptr_base_path_rc(loan_path: &Rc<LoanPath>) -> Rc<LoanPath> {
+    //! The equivalent of `owned_ptr_base_path` for an &Rc<LoanPath> rather than
+    //! a &LoanPath.
+
+    return match owned_ptr_base_path_helper(loan_path) {
+        Some(new_loan_path) => new_loan_path,
+        None => loan_path.clone()
+    };
+
+    fn owned_ptr_base_path_helper(loan_path: &Rc<LoanPath>) -> Option<Rc<LoanPath>> {
+        match **loan_path {
+            LpVar(_) | LpUpvar(_) => None,
+            LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => {
+                match owned_ptr_base_path_helper(lp_base) {
+                    v @ Some(_) => v,
+                    None => Some(lp_base.clone())
+                }
+            }
+            LpExtend(ref lp_base, _, _) => owned_ptr_base_path_helper(lp_base)
+        }
+    }
+}
+
 struct CheckLoanCtxt<'a> {
     bccx: &'a BorrowckCtxt<'a>,
     dfcx_loans: &'a LoanDataFlow<'a>,