From 970c613e4a785325469d4f694a16505d5deac17a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sun, 3 Dec 2017 13:49:01 +0100
Subject: [PATCH] Add sync module to rustc_data_structures

---
 src/Cargo.lock                                |   38 +-
 src/bootstrap/bin/rustc.rs                    |    4 +
 src/bootstrap/compile.rs                      |    3 +
 src/bootstrap/config.rs                       |    3 +
 src/librustc/Cargo.toml                       |    1 -
 src/librustc/lib.rs                           |    1 -
 src/librustc/middle/cstore.rs                 |    2 +-
 src/librustc_data_structures/Cargo.toml       |    7 +
 src/librustc_data_structures/lib.rs           |    9 +
 .../owning_ref/LICENSE                        |   21 +
 .../owning_ref/mod.rs                         | 1902 +++++++++++++++++
 src/librustc_data_structures/sync.rs          |  403 ++++
 src/librustc_driver/Cargo.toml                |    1 -
 src/librustc_metadata/Cargo.toml              |    1 -
 src/librustc_metadata/cstore.rs               |    2 +-
 src/librustc_metadata/lib.rs                  |    1 -
 src/librustc_metadata/locator.rs              |    2 +-
 src/librustc_trans/Cargo.toml                 |    1 -
 src/librustc_trans/lib.rs                     |    1 -
 src/librustc_trans/metadata.rs                |    2 +-
 src/librustc_trans_utils/Cargo.toml           |    1 -
 src/librustc_trans_utils/lib.rs               |    1 -
 src/librustc_trans_utils/trans_crate.rs       |    2 +-
 src/tools/tidy/src/lib.rs                     |    1 +
 24 files changed, 2391 insertions(+), 19 deletions(-)
 create mode 100644 src/librustc_data_structures/owning_ref/LICENSE
 create mode 100644 src/librustc_data_structures/owning_ref/mod.rs
 create mode 100644 src/librustc_data_structures/sync.rs

diff --git a/src/Cargo.lock b/src/Cargo.lock
index 8cf9c3f238107..54a58854f0a27 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1313,6 +1313,27 @@ dependencies = [
  "unwind 0.0.0",
 ]
 
+[[package]]
+name = "parking_lot"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "percent-encoding"
 version = "1.0.1"
@@ -1649,7 +1670,6 @@ dependencies = [
  "graphviz 0.0.0",
  "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
  "rustc_back 0.0.0",
  "rustc_const_math 0.0.0",
@@ -1773,8 +1793,12 @@ dependencies = [
 name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
+ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
+ "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1786,7 +1810,6 @@ dependencies = [
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_allocator 0.0.0",
  "rustc_back 0.0.0",
@@ -1874,7 +1897,6 @@ version = "0.0.0"
 dependencies = [
  "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -1993,7 +2015,6 @@ dependencies = [
  "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
@@ -2020,7 +2041,6 @@ dependencies = [
  "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2228,6 +2248,11 @@ name = "smallvec"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "smallvec"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "socket2"
 version = "0.2.4"
@@ -2820,6 +2845,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7"
 "checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
+"checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412"
+"checksum parking_lot_core 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "12d20aac4f67aa75f681aded784bac91f910ba3f2af1812573cdcf687414e122"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
@@ -2871,6 +2898,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8"
 "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
 "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
+"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8"
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 30afd52f44824..37336a56d76c2 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -265,6 +265,10 @@ fn main() {
         }
     }
 
+    if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
+        cmd.arg("--cfg").arg("parallel_queries");
+    }
+
     let color = match env::var("RUSTC_COLOR") {
         Ok(s) => usize::from_str(&s).expect("RUSTC_COLOR should be an integer"),
         Err(_) => 0,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index db013691bb1b8..4c76230ced8bc 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -561,6 +561,9 @@ pub fn rustc_cargo(build: &Build,
     if let Some(ref s) = build.config.rustc_default_linker {
         cargo.env("CFG_DEFAULT_LINKER", s);
     }
+    if build.config.rustc_parallel_queries {
+        cargo.env("RUSTC_PARALLEL_QUERIES", "1");
+    }
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 9dd37d8e4560c..87b1db33a7a85 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -87,6 +87,7 @@ pub struct Config {
     pub rust_debuginfo_lines: bool,
     pub rust_debuginfo_only_std: bool,
     pub rust_rpath: bool,
+    pub rustc_parallel_queries: bool,
     pub rustc_default_linker: Option<String>,
     pub rust_optimize_tests: bool,
     pub rust_debuginfo_tests: bool,
@@ -266,6 +267,7 @@ struct Rust {
     debuginfo: Option<bool>,
     debuginfo_lines: Option<bool>,
     debuginfo_only_std: Option<bool>,
+    experimental_parallel_queries: Option<bool>,
     debug_jemalloc: Option<bool>,
     use_jemalloc: Option<bool>,
     backtrace: Option<bool>,
@@ -474,6 +476,7 @@ impl Config {
             set(&mut config.rust_dist_src, rust.dist_src);
             set(&mut config.quiet_tests, rust.quiet_tests);
             set(&mut config.test_miri, rust.test_miri);
+            config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
             config.rustc_default_linker = rust.default_linker.clone();
             config.musl_root = rust.musl_root.clone().map(PathBuf::from);
             config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index a8892cb22101a..3a4b30294db74 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -15,7 +15,6 @@ fmt_macros = { path = "../libfmt_macros" }
 graphviz = { path = "../libgraphviz" }
 jobserver = "0.1"
 log = "0.3"
-owning_ref = "0.3.3"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_back = { path = "../librustc_back" }
 rustc_const_math = { path = "../librustc_const_math" }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index bf7484156a64a..8dc927c451b89 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -77,7 +77,6 @@ extern crate getopts;
 extern crate graphviz;
 #[cfg(windows)]
 extern crate libc;
-extern crate owning_ref;
 extern crate rustc_back;
 #[macro_use] extern crate rustc_data_structures;
 extern crate serialize;
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 914fb0670b605..9708afd204593 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -38,7 +38,7 @@ use std::any::Any;
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
-use owning_ref::ErasedBoxRef;
+use rustc_data_structures::owning_ref::ErasedBoxRef;
 use syntax::ast;
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 343b1ed68b804..82075ce1f1f79 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -11,3 +11,10 @@ crate-type = ["dylib"]
 [dependencies]
 log = "0.3"
 serialize = { path = "../libserialize" }
+cfg-if = "0.1.2"
+stable_deref_trait = "1.0.0"
+parking_lot_core = "0.2.8"
+
+[dependencies.parking_lot]
+version = "0.5"
+features = ["nightly"]
\ No newline at end of file
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 8862ba3545eba..24048e606df47 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -31,7 +31,10 @@
 #![feature(i128)]
 #![feature(conservative_impl_trait)]
 #![feature(specialization)]
+#![feature(optin_builtin_traits)]
 #![feature(underscore_lifetimes)]
+#![feature(macro_vis_matcher)]
+#![feature(allow_internal_unstable)]
 
 #![cfg_attr(unix, feature(libc))]
 #![cfg_attr(test, feature(test))]
@@ -42,6 +45,10 @@ extern crate log;
 extern crate serialize as rustc_serialize; // used by deriving
 #[cfg(unix)]
 extern crate libc;
+extern crate parking_lot;
+#[macro_use]
+extern crate cfg_if;
+extern crate stable_deref_trait;
 
 pub use rustc_serialize::hex::ToHex;
 
@@ -67,6 +74,8 @@ pub mod tuple_slice;
 pub mod veccell;
 pub mod control_flow_graph;
 pub mod flock;
+pub mod sync;
+pub mod owning_ref;
 
 // See comments in src/librustc/lib.rs
 #[doc(hidden)]
diff --git a/src/librustc_data_structures/owning_ref/LICENSE b/src/librustc_data_structures/owning_ref/LICENSE
new file mode 100644
index 0000000000000..dff72d1e43251
--- /dev/null
+++ b/src/librustc_data_structures/owning_ref/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Marvin Löbel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/src/librustc_data_structures/owning_ref/mod.rs b/src/librustc_data_structures/owning_ref/mod.rs
new file mode 100644
index 0000000000000..23e0733748b4a
--- /dev/null
+++ b/src/librustc_data_structures/owning_ref/mod.rs
@@ -0,0 +1,1902 @@
+#![warn(missing_docs)]
+
+/*!
+# An owning reference.
+
+This crate provides the _owning reference_ types `OwningRef` and `OwningRefMut`
+that enables it to bundle a reference together with the owner of the data it points to.
+This allows moving and dropping of a `OwningRef` without needing to recreate the reference.
+
+This can sometimes be useful because Rust borrowing rules normally prevent
+moving a type that has been moved from. For example, this kind of code gets rejected:
+
+```rust,ignore
+fn return_owned_and_referenced<'a>() -> (Vec<u8>, &'a [u8]) {
+    let v = vec![1, 2, 3, 4];
+    let s = &v[1..3];
+    (v, s)
+}
+```
+
+Even though, from a memory-layout point of view, this can be entirely safe
+if the new location of the vector still lives longer than the lifetime `'a`
+of the reference because the backing allocation of the vector does not change.
+
+This library enables this safe usage by keeping the owner and the reference
+bundled together in a wrapper type that ensure that lifetime constraint:
+
+```rust
+# extern crate owning_ref;
+# use owning_ref::OwningRef;
+# fn main() {
+fn return_owned_and_referenced() -> OwningRef<Vec<u8>, [u8]> {
+    let v = vec![1, 2, 3, 4];
+    let or = OwningRef::new(v);
+    let or = or.map(|v| &v[1..3]);
+    or
+}
+# }
+```
+
+It works by requiring owner types to dereference to stable memory locations
+and preventing mutable access to root containers, which in practice requires heap allocation
+as provided by `Box<T>`, `Rc<T>`, etc.
+
+Also provided are typedefs for common owner type combinations,
+which allow for less verbose type signatures. For example, `BoxRef<T>` instead of `OwningRef<Box<T>, T>`.
+
+The crate also provides the more advanced `OwningHandle` type,
+which allows more freedom in bundling a dependent handle object
+along with the data it depends on, at the cost of some unsafe needed in the API.
+See the documentation around `OwningHandle` for more details.
+
+# Examples
+
+## Basics
+
+```
+extern crate owning_ref;
+use owning_ref::BoxRef;
+
+fn main() {
+    // Create an array owned by a Box.
+    let arr = Box::new([1, 2, 3, 4]) as Box<[i32]>;
+
+    // Transfer into a BoxRef.
+    let arr: BoxRef<[i32]> = BoxRef::new(arr);
+    assert_eq!(&*arr, &[1, 2, 3, 4]);
+
+    // We can slice the array without losing ownership or changing type.
+    let arr: BoxRef<[i32]> = arr.map(|arr| &arr[1..3]);
+    assert_eq!(&*arr, &[2, 3]);
+
+    // Also works for Arc, Rc, String and Vec!
+}
+```
+
+## Caching a reference to a struct field
+
+```
+extern crate owning_ref;
+use owning_ref::BoxRef;
+
+fn main() {
+    struct Foo {
+        tag: u32,
+        x: u16,
+        y: u16,
+        z: u16,
+    }
+    let foo = Foo { tag: 1, x: 100, y: 200, z: 300 };
+
+    let or = BoxRef::new(Box::new(foo)).map(|foo| {
+        match foo.tag {
+            0 => &foo.x,
+            1 => &foo.y,
+            2 => &foo.z,
+            _ => panic!(),
+        }
+    });
+
+    assert_eq!(*or, 200);
+}
+```
+
+## Caching a reference to an entry in a vector
+
+```
+extern crate owning_ref;
+use owning_ref::VecRef;
+
+fn main() {
+    let v = VecRef::new(vec![1, 2, 3, 4, 5]).map(|v| &v[3]);
+    assert_eq!(*v, 4);
+}
+```
+
+## Caching a subslice of a String
+
+```
+extern crate owning_ref;
+use owning_ref::StringRef;
+
+fn main() {
+    let s = StringRef::new("hello world".to_owned())
+        .map(|s| s.split(' ').nth(1).unwrap());
+
+    assert_eq!(&*s, "world");
+}
+```
+
+## Reference counted slices that share ownership of the backing storage
+
+```
+extern crate owning_ref;
+use owning_ref::RcRef;
+use std::rc::Rc;
+
+fn main() {
+    let rc: RcRef<[i32]> = RcRef::new(Rc::new([1, 2, 3, 4]) as Rc<[i32]>);
+    assert_eq!(&*rc, &[1, 2, 3, 4]);
+
+    let rc_a: RcRef<[i32]> = rc.clone().map(|s| &s[0..2]);
+    let rc_b = rc.clone().map(|s| &s[1..3]);
+    let rc_c = rc.clone().map(|s| &s[2..4]);
+    assert_eq!(&*rc_a, &[1, 2]);
+    assert_eq!(&*rc_b, &[2, 3]);
+    assert_eq!(&*rc_c, &[3, 4]);
+
+    let rc_c_a = rc_c.clone().map(|s| &s[1]);
+    assert_eq!(&*rc_c_a, &4);
+}
+```
+
+## Atomic reference counted slices that share ownership of the backing storage
+
+```
+extern crate owning_ref;
+use owning_ref::ArcRef;
+use std::sync::Arc;
+
+fn main() {
+    use std::thread;
+
+    fn par_sum(rc: ArcRef<[i32]>) -> i32 {
+        if rc.len() == 0 {
+            return 0;
+        } else if rc.len() == 1 {
+            return rc[0];
+        }
+        let mid = rc.len() / 2;
+        let left = rc.clone().map(|s| &s[..mid]);
+        let right = rc.map(|s| &s[mid..]);
+
+        let left = thread::spawn(move || par_sum(left));
+        let right = thread::spawn(move || par_sum(right));
+
+        left.join().unwrap() + right.join().unwrap()
+    }
+
+    let rc: Arc<[i32]> = Arc::new([1, 2, 3, 4]);
+    let rc: ArcRef<[i32]> = rc.into();
+
+    assert_eq!(par_sum(rc), 10);
+}
+```
+
+## References into RAII locks
+
+```
+extern crate owning_ref;
+use owning_ref::RefRef;
+use std::cell::{RefCell, Ref};
+
+fn main() {
+    let refcell = RefCell::new((1, 2, 3, 4));
+    // Also works with Mutex and RwLock
+
+    let refref = {
+        let refref = RefRef::new(refcell.borrow()).map(|x| &x.3);
+        assert_eq!(*refref, 4);
+
+        // We move the RAII lock and the reference to one of
+        // the subfields in the data it guards here:
+        refref
+    };
+
+    assert_eq!(*refref, 4);
+
+    drop(refref);
+
+    assert_eq!(*refcell.borrow(), (1, 2, 3, 4));
+}
+```
+
+## Mutable reference
+
+When the owned container implements `DerefMut`, it is also possible to make
+a _mutable owning reference_. (E.g. with `Box`, `RefMut`, `MutexGuard`)
+
+```
+extern crate owning_ref;
+use owning_ref::RefMutRefMut;
+use std::cell::{RefCell, RefMut};
+
+fn main() {
+    let refcell = RefCell::new((1, 2, 3, 4));
+
+    let mut refmut_refmut = {
+        let mut refmut_refmut = RefMutRefMut::new(refcell.borrow_mut()).map_mut(|x| &mut x.3);
+        assert_eq!(*refmut_refmut, 4);
+        *refmut_refmut *= 2;
+
+        refmut_refmut
+    };
+
+    assert_eq!(*refmut_refmut, 8);
+    *refmut_refmut *= 2;
+
+    drop(refmut_refmut);
+
+    assert_eq!(*refcell.borrow(), (1, 2, 3, 16));
+}
+```
+*/
+
+pub use stable_deref_trait::{StableDeref as StableAddress, CloneStableDeref as CloneStableAddress};
+
+/// An owning reference.
+///
+/// This wraps an owner `O` and a reference `&T` pointing
+/// at something reachable from `O::Target` while keeping
+/// the ability to move `self` around.
+///
+/// The owner is usually a pointer that points at some base type.
+///
+/// For more details and examples, see the module and method docs.
+pub struct OwningRef<O, T: ?Sized> {
+    owner: O,
+    reference: *const T,
+}
+
+/// An mutable owning reference.
+///
+/// This wraps an owner `O` and a reference `&mut T` pointing
+/// at something reachable from `O::Target` while keeping
+/// the ability to move `self` around.
+///
+/// The owner is usually a pointer that points at some base type.
+///
+/// For more details and examples, see the module and method docs.
+pub struct OwningRefMut<O, T: ?Sized> {
+    owner: O,
+    reference: *mut T,
+}
+
+/// Helper trait for an erased concrete type an owner dereferences to.
+/// This is used in form of a trait object for keeping
+/// something around to (virtually) call the destructor.
+pub trait Erased {}
+impl<T> Erased for T {}
+
+/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// for example `Box<T> -> Box<Erased>`. This would be unneeded with
+/// higher kinded types support in the language.
+pub unsafe trait IntoErased<'a> {
+    /// Owner with the dereference type substituted to `Erased`.
+    type Erased;
+    /// Perform the type erasure.
+    fn into_erased(self) -> Self::Erased;
+}
+
+/// Helper trait for erasing the concrete type of what an owner derferences to,
+/// for example `Box<T> -> Box<Erased + Send + Sync>`. This would be unneeded with
+/// higher kinded types support in the language.
+pub unsafe trait IntoErasedSendSync<'a>: Send + Sync {
+    /// Owner with the dereference type substituted to `Erased + Send + Sync`.
+    type Erased: Send + Sync;
+    /// Perform the type erasure.
+    fn into_erased_send_sync(self) -> Self::Erased;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// OwningRef
+/////////////////////////////////////////////////////////////////////////////
+
+impl<O, T: ?Sized> OwningRef<O, T> {
+    /// Creates a new owning reference from a owner
+    /// initialized to the direct dereference of it.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRef;
+    ///
+    /// fn main() {
+    ///     let owning_ref = OwningRef::new(Box::new(42));
+    ///     assert_eq!(*owning_ref, 42);
+    /// }
+    /// ```
+    pub fn new(o: O) -> Self
+        where O: StableAddress,
+              O: Deref<Target = T>,
+    {
+        OwningRef {
+            reference: &*o,
+            owner: o,
+        }
+    }
+
+    /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait.
+    /// Instead, the caller is responsible to make the same promises as implementing the trait.
+    ///
+    /// This is useful for cases where coherence rules prevents implementing the trait
+    /// without adding a dependency to this crate in a third-party library.
+    pub unsafe fn new_assert_stable_address(o: O) -> Self
+        where O: Deref<Target = T>,
+    {
+        OwningRef {
+            reference: &*o,
+            owner: o,
+        }
+    }
+
+    /// Converts `self` into a new owning reference that points at something reachable
+    /// from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRef;
+    ///
+    /// fn main() {
+    ///     let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref = owning_ref.map(|array| &array[2]);
+    ///     assert_eq!(*owning_ref, 3);
+    /// }
+    /// ```
+    pub fn map<F, U: ?Sized>(self, f: F) -> OwningRef<O, U>
+        where O: StableAddress,
+              F: FnOnce(&T) -> &U
+    {
+        OwningRef {
+            reference: f(&self),
+            owner: self.owner,
+        }
+    }
+
+    /// Tries to convert `self` into a new owning reference that points
+    /// at something reachable from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRef;
+    ///
+    /// fn main() {
+    ///     let owning_ref = OwningRef::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref = owning_ref.try_map(|array| {
+    ///         if array[2] == 3 { Ok(&array[2]) } else { Err(()) }
+    ///     });
+    ///     assert_eq!(*owning_ref.unwrap(), 3);
+    /// }
+    /// ```
+    pub fn try_map<F, U: ?Sized, E>(self, f: F) -> Result<OwningRef<O, U>, E>
+        where O: StableAddress,
+              F: FnOnce(&T) -> Result<&U, E>
+    {
+        Ok(OwningRef {
+            reference: f(&self)?,
+            owner: self.owner,
+        })
+    }
+
+    /// Converts `self` into a new owning reference with a different owner type.
+    ///
+    /// The new owner type needs to still contain the original owner in some way
+    /// so that the reference into it remains valid. This function is marked unsafe
+    /// because the user needs to manually uphold this guarantee.
+    pub unsafe fn map_owner<F, P>(self, f: F) -> OwningRef<P, T>
+        where O: StableAddress,
+              P: StableAddress,
+              F: FnOnce(O) -> P
+    {
+        OwningRef {
+            reference: self.reference,
+            owner: f(self.owner),
+        }
+    }
+
+    /// Converts `self` into a new owning reference where the owner is wrapped
+    /// in an additional `Box<O>`.
+    ///
+    /// This can be used to safely erase the owner of any `OwningRef<O, T>`
+    /// to a `OwningRef<Box<Erased>, T>`.
+    pub fn map_owner_box(self) -> OwningRef<Box<O>, T> {
+        OwningRef {
+            reference: self.reference,
+            owner: Box::new(self.owner),
+        }
+    }
+
+    /// Erases the concrete base type of the owner with a trait object.
+    ///
+    /// This allows mixing of owned references with different owner base types.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::{OwningRef, Erased};
+    ///
+    /// fn main() {
+    ///     // NB: Using the concrete types here for explicitnes.
+    ///     // For less verbose code type aliases like `BoxRef` are provided.
+    ///
+    ///     let owning_ref_a: OwningRef<Box<[i32; 4]>, [i32; 4]>
+    ///         = OwningRef::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     let owning_ref_b: OwningRef<Box<Vec<(i32, bool)>>, Vec<(i32, bool)>>
+    ///         = OwningRef::new(Box::new(vec![(0, false), (1, true)]));
+    ///
+    ///     let owning_ref_a: OwningRef<Box<[i32; 4]>, i32>
+    ///         = owning_ref_a.map(|a| &a[0]);
+    ///
+    ///     let owning_ref_b: OwningRef<Box<Vec<(i32, bool)>>, i32>
+    ///         = owning_ref_b.map(|a| &a[1].0);
+    ///
+    ///     let owning_refs: [OwningRef<Box<Erased>, i32>; 2]
+    ///         = [owning_ref_a.erase_owner(), owning_ref_b.erase_owner()];
+    ///
+    ///     assert_eq!(*owning_refs[0], 1);
+    ///     assert_eq!(*owning_refs[1], 1);
+    /// }
+    /// ```
+    pub fn erase_owner<'a>(self) -> OwningRef<O::Erased, T>
+        where O: IntoErased<'a>,
+    {
+        OwningRef {
+            reference: self.reference,
+            owner: self.owner.into_erased(),
+        }
+    }
+
+    /// Erases the concrete base type of the owner with a trait object which implements `Send` and `Sync`.
+    ///
+    /// This allows mixing of owned references with different owner base types.
+    pub fn erase_send_sync_owner<'a>(self) -> OwningRef<O::Erased, T>
+        where O: IntoErasedSendSync<'a>,
+    {
+        OwningRef {
+            reference: self.reference,
+            owner: self.owner.into_erased_send_sync(),
+        }
+    }
+
+    // TODO: wrap_owner
+
+    // FIXME: Naming convention?
+    /// A getter for the underlying owner.
+    pub fn owner(&self) -> &O {
+        &self.owner
+    }
+
+    // FIXME: Naming convention?
+    /// Discards the reference and retrieves the owner.
+    pub fn into_inner(self) -> O {
+        self.owner
+    }
+}
+
+impl<O, T: ?Sized> OwningRefMut<O, T> {
+    /// Creates a new owning reference from a owner
+    /// initialized to the direct dereference of it.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRefMut;
+    ///
+    /// fn main() {
+    ///     let owning_ref_mut = OwningRefMut::new(Box::new(42));
+    ///     assert_eq!(*owning_ref_mut, 42);
+    /// }
+    /// ```
+    pub fn new(mut o: O) -> Self
+        where O: StableAddress,
+              O: DerefMut<Target = T>,
+    {
+        OwningRefMut {
+            reference: &mut *o,
+            owner: o,
+        }
+    }
+
+    /// Like `new`, but doesn’t require `O` to implement the `StableAddress` trait.
+    /// Instead, the caller is responsible to make the same promises as implementing the trait.
+    ///
+    /// This is useful for cases where coherence rules prevents implementing the trait
+    /// without adding a dependency to this crate in a third-party library.
+    pub unsafe fn new_assert_stable_address(mut o: O) -> Self
+        where O: DerefMut<Target = T>,
+    {
+        OwningRefMut {
+            reference: &mut *o,
+            owner: o,
+        }
+    }
+
+    /// Converts `self` into a new _shared_ owning reference that points at
+    /// something reachable from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRefMut;
+    ///
+    /// fn main() {
+    ///     let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref = owning_ref_mut.map(|array| &array[2]);
+    ///     assert_eq!(*owning_ref, 3);
+    /// }
+    /// ```
+    pub fn map<F, U: ?Sized>(mut self, f: F) -> OwningRef<O, U>
+        where O: StableAddress,
+              F: FnOnce(&mut T) -> &U
+    {
+        OwningRef {
+            reference: f(&mut self),
+            owner: self.owner,
+        }
+    }
+
+    /// Converts `self` into a new _mutable_ owning reference that points at
+    /// something reachable from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRefMut;
+    ///
+    /// fn main() {
+    ///     let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref_mut = owning_ref_mut.map_mut(|array| &mut array[2]);
+    ///     assert_eq!(*owning_ref_mut, 3);
+    /// }
+    /// ```
+    pub fn map_mut<F, U: ?Sized>(mut self, f: F) -> OwningRefMut<O, U>
+        where O: StableAddress,
+              F: FnOnce(&mut T) -> &mut U
+    {
+        OwningRefMut {
+            reference: f(&mut self),
+            owner: self.owner,
+        }
+    }
+
+    /// Tries to convert `self` into a new _shared_ owning reference that points
+    /// at something reachable from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRefMut;
+    ///
+    /// fn main() {
+    ///     let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref = owning_ref_mut.try_map(|array| {
+    ///         if array[2] == 3 { Ok(&array[2]) } else { Err(()) }
+    ///     });
+    ///     assert_eq!(*owning_ref.unwrap(), 3);
+    /// }
+    /// ```
+    pub fn try_map<F, U: ?Sized, E>(mut self, f: F) -> Result<OwningRef<O, U>, E>
+        where O: StableAddress,
+              F: FnOnce(&mut T) -> Result<&U, E>
+    {
+        Ok(OwningRef {
+            reference: f(&mut self)?,
+            owner: self.owner,
+        })
+    }
+
+    /// Tries to convert `self` into a new _mutable_ owning reference that points
+    /// at something reachable from the previous one.
+    ///
+    /// This can be a reference to a field of `U`, something reachable from a field of
+    /// `U`, or even something unrelated with a `'static` lifetime.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::OwningRefMut;
+    ///
+    /// fn main() {
+    ///     let owning_ref_mut = OwningRefMut::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     // create a owning reference that points at the
+    ///     // third element of the array.
+    ///     let owning_ref_mut = owning_ref_mut.try_map_mut(|array| {
+    ///         if array[2] == 3 { Ok(&mut array[2]) } else { Err(()) }
+    ///     });
+    ///     assert_eq!(*owning_ref_mut.unwrap(), 3);
+    /// }
+    /// ```
+    pub fn try_map_mut<F, U: ?Sized, E>(mut self, f: F) -> Result<OwningRefMut<O, U>, E>
+        where O: StableAddress,
+              F: FnOnce(&mut T) -> Result<&mut U, E>
+    {
+        Ok(OwningRefMut {
+            reference: f(&mut self)?,
+            owner: self.owner,
+        })
+    }
+
+    /// Converts `self` into a new owning reference with a different owner type.
+    ///
+    /// The new owner type needs to still contain the original owner in some way
+    /// so that the reference into it remains valid. This function is marked unsafe
+    /// because the user needs to manually uphold this guarantee.
+    pub unsafe fn map_owner<F, P>(self, f: F) -> OwningRefMut<P, T>
+        where O: StableAddress,
+              P: StableAddress,
+              F: FnOnce(O) -> P
+    {
+        OwningRefMut {
+            reference: self.reference,
+            owner: f(self.owner),
+        }
+    }
+
+    /// Converts `self` into a new owning reference where the owner is wrapped
+    /// in an additional `Box<O>`.
+    ///
+    /// This can be used to safely erase the owner of any `OwningRefMut<O, T>`
+    /// to a `OwningRefMut<Box<Erased>, T>`.
+    pub fn map_owner_box(self) -> OwningRefMut<Box<O>, T> {
+        OwningRefMut {
+            reference: self.reference,
+            owner: Box::new(self.owner),
+        }
+    }
+
+    /// Erases the concrete base type of the owner with a trait object.
+    ///
+    /// This allows mixing of owned references with different owner base types.
+    ///
+    /// # Example
+    /// ```
+    /// extern crate owning_ref;
+    /// use owning_ref::{OwningRefMut, Erased};
+    ///
+    /// fn main() {
+    ///     // NB: Using the concrete types here for explicitnes.
+    ///     // For less verbose code type aliases like `BoxRef` are provided.
+    ///
+    ///     let owning_ref_mut_a: OwningRefMut<Box<[i32; 4]>, [i32; 4]>
+    ///         = OwningRefMut::new(Box::new([1, 2, 3, 4]));
+    ///
+    ///     let owning_ref_mut_b: OwningRefMut<Box<Vec<(i32, bool)>>, Vec<(i32, bool)>>
+    ///         = OwningRefMut::new(Box::new(vec![(0, false), (1, true)]));
+    ///
+    ///     let owning_ref_mut_a: OwningRefMut<Box<[i32; 4]>, i32>
+    ///         = owning_ref_mut_a.map_mut(|a| &mut a[0]);
+    ///
+    ///     let owning_ref_mut_b: OwningRefMut<Box<Vec<(i32, bool)>>, i32>
+    ///         = owning_ref_mut_b.map_mut(|a| &mut a[1].0);
+    ///
+    ///     let owning_refs_mut: [OwningRefMut<Box<Erased>, i32>; 2]
+    ///         = [owning_ref_mut_a.erase_owner(), owning_ref_mut_b.erase_owner()];
+    ///
+    ///     assert_eq!(*owning_refs_mut[0], 1);
+    ///     assert_eq!(*owning_refs_mut[1], 1);
+    /// }
+    /// ```
+    pub fn erase_owner<'a>(self) -> OwningRefMut<O::Erased, T>
+        where O: IntoErased<'a>,
+    {
+        OwningRefMut {
+            reference: self.reference,
+            owner: self.owner.into_erased(),
+        }
+    }
+
+    // TODO: wrap_owner
+
+    // FIXME: Naming convention?
+    /// A getter for the underlying owner.
+    pub fn owner(&self) -> &O {
+        &self.owner
+    }
+
+    // FIXME: Naming convention?
+    /// Discards the reference and retrieves the owner.
+    pub fn into_inner(self) -> O {
+        self.owner
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// OwningHandle
+/////////////////////////////////////////////////////////////////////////////
+
+use std::ops::{Deref, DerefMut};
+
+/// `OwningHandle` is a complement to `OwningRef`. Where `OwningRef` allows
+/// consumers to pass around an owned object and a dependent reference,
+/// `OwningHandle` contains an owned object and a dependent _object_.
+///
+/// `OwningHandle` can encapsulate a `RefMut` along with its associated
+/// `RefCell`, or an `RwLockReadGuard` along with its associated `RwLock`.
+/// However, the API is completely generic and there are no restrictions on
+/// what types of owning and dependent objects may be used.
+///
+/// `OwningHandle` is created by passing an owner object (which dereferences
+/// to a stable address) along with a callback which receives a pointer to
+/// that stable location. The callback may then dereference the pointer and
+/// mint a dependent object, with the guarantee that the returned object will
+/// not outlive the referent of the pointer.
+///
+/// Since the callback needs to dereference a raw pointer, it requires `unsafe`
+/// code. To avoid forcing this unsafety on most callers, the `ToHandle` trait is
+/// implemented for common data structures. Types that implement `ToHandle` can
+/// be wrapped into an `OwningHandle` without passing a callback.
+pub struct OwningHandle<O, H>
+    where O: StableAddress, H: Deref,
+{
+    handle: H,
+    _owner: O,
+}
+
+impl<O, H> Deref for OwningHandle<O, H>
+    where O: StableAddress, H: Deref,
+{
+    type Target = H::Target;
+    fn deref(&self) -> &H::Target {
+        self.handle.deref()
+    }
+}
+
+unsafe impl<O, H> StableAddress for OwningHandle<O, H>
+    where O: StableAddress, H: StableAddress,
+{}
+
+impl<O, H> DerefMut for OwningHandle<O, H>
+    where O: StableAddress, H: DerefMut,
+{
+    fn deref_mut(&mut self) -> &mut H::Target {
+        self.handle.deref_mut()
+    }
+}
+
+/// Trait to implement the conversion of owner to handle for common types.
+pub trait ToHandle {
+    /// The type of handle to be encapsulated by the OwningHandle.
+    type Handle: Deref;
+
+    /// Given an appropriately-long-lived pointer to ourselves, create a
+    /// handle to be encapsulated by the `OwningHandle`.
+    unsafe fn to_handle(x: *const Self) -> Self::Handle;
+}
+
+/// Trait to implement the conversion of owner to mutable handle for common types.
+pub trait ToHandleMut {
+    /// The type of handle to be encapsulated by the OwningHandle.
+    type HandleMut: DerefMut;
+
+    /// Given an appropriately-long-lived pointer to ourselves, create a
+    /// mutable handle to be encapsulated by the `OwningHandle`.
+    unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut;
+}
+
+impl<O, H> OwningHandle<O, H>
+    where O: StableAddress, O::Target: ToHandle<Handle = H>, H: Deref,
+{
+    /// Create a new `OwningHandle` for a type that implements `ToHandle`. For types
+    /// that don't implement `ToHandle`, callers may invoke `new_with_fn`, which accepts
+    /// a callback to perform the conversion.
+    pub fn new(o: O) -> Self {
+        OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle(x) })
+    }
+}
+
+impl<O, H> OwningHandle<O, H>
+    where O: StableAddress, O::Target: ToHandleMut<HandleMut = H>, H: DerefMut,
+{
+    /// Create a new mutable `OwningHandle` for a type that implements `ToHandleMut`.
+    pub fn new_mut(o: O) -> Self {
+        OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle_mut(x) })
+    }
+}
+
+impl<O, H> OwningHandle<O, H>
+    where O: StableAddress, H: Deref,
+{
+    /// Create a new OwningHandle. The provided callback will be invoked with
+    /// a pointer to the object owned by `o`, and the returned value is stored
+    /// as the object to which this `OwningHandle` will forward `Deref` and
+    /// `DerefMut`.
+    pub fn new_with_fn<F>(o: O, f: F) -> Self
+        where F: FnOnce(*const O::Target) -> H
+    {
+        let h: H;
+        {
+            h = f(o.deref() as *const O::Target);
+        }
+
+        OwningHandle {
+          handle: h,
+          _owner: o,
+        }
+    }
+
+    /// Create a new OwningHandle. The provided callback will be invoked with
+    /// a pointer to the object owned by `o`, and the returned value is stored
+    /// as the object to which this `OwningHandle` will forward `Deref` and
+    /// `DerefMut`.
+    pub fn try_new<F, E>(o: O, f: F) -> Result<Self, E>
+        where F: FnOnce(*const O::Target) -> Result<H, E>
+    {
+        let h: H;
+        {
+            h = f(o.deref() as *const O::Target)?;
+        }
+
+        Ok(OwningHandle {
+          handle: h,
+          _owner: o,
+        })
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// std traits
+/////////////////////////////////////////////////////////////////////////////
+
+use std::convert::From;
+use std::fmt::{self, Debug};
+use std::marker::{Send, Sync};
+use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering};
+use std::hash::{Hash, Hasher};
+use std::borrow::Borrow;
+
+impl<O, T: ?Sized> Deref for OwningRef<O, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            &*self.reference
+        }
+    }
+}
+
+impl<O, T: ?Sized> Deref for OwningRefMut<O, T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe {
+            &*self.reference
+        }
+    }
+}
+
+impl<O, T: ?Sized> DerefMut for OwningRefMut<O, T> {
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe {
+            &mut *self.reference
+        }
+    }
+}
+
+unsafe impl<O, T: ?Sized> StableAddress for OwningRef<O, T> {}
+
+impl<O, T: ?Sized> AsRef<T> for OwningRef<O, T> {
+    fn as_ref(&self) -> &T {
+        &*self
+    }
+}
+
+impl<O, T: ?Sized> AsRef<T> for OwningRefMut<O, T> {
+    fn as_ref(&self) -> &T {
+        &*self
+    }
+}
+
+impl<O, T: ?Sized> AsMut<T> for OwningRefMut<O, T> {
+    fn as_mut(&mut self) -> &mut T {
+        &mut *self
+    }
+}
+
+impl<O, T: ?Sized> Borrow<T> for OwningRef<O, T> {
+    fn borrow(&self) -> &T {
+        &*self
+    }
+}
+
+impl<O, T: ?Sized> From<O> for OwningRef<O, T>
+    where O: StableAddress,
+          O: Deref<Target = T>,
+{
+    fn from(owner: O) -> Self {
+        OwningRef::new(owner)
+    }
+}
+
+impl<O, T: ?Sized> From<O> for OwningRefMut<O, T>
+    where O: StableAddress,
+          O: DerefMut<Target = T>
+{
+    fn from(owner: O) -> Self {
+        OwningRefMut::new(owner)
+    }
+}
+
+impl<O, T: ?Sized> From<OwningRefMut<O, T>> for OwningRef<O, T>
+    where O: StableAddress,
+          O: DerefMut<Target = T>
+{
+    fn from(other: OwningRefMut<O, T>) -> Self {
+        OwningRef {
+            owner: other.owner,
+            reference: other.reference,
+        }
+    }
+}
+
+// ^ FIXME: Is a Into impl for calling into_inner() possible as well?
+
+impl<O, T: ?Sized> Debug for OwningRef<O, T>
+    where O: Debug,
+          T: Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f,
+               "OwningRef {{ owner: {:?}, reference: {:?} }}",
+               self.owner(),
+               &**self)
+    }
+}
+
+impl<O, T: ?Sized> Debug for OwningRefMut<O, T>
+    where O: Debug,
+          T: Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f,
+               "OwningRefMut {{ owner: {:?}, reference: {:?} }}",
+               self.owner(),
+               &**self)
+    }
+}
+
+impl<O, T: ?Sized> Clone for OwningRef<O, T>
+    where O: CloneStableAddress,
+{
+    fn clone(&self) -> Self {
+        OwningRef {
+            owner: self.owner.clone(),
+            reference: self.reference,
+        }
+    }
+}
+
+unsafe impl<O, T: ?Sized> CloneStableAddress for OwningRef<O, T>
+    where O: CloneStableAddress {}
+
+unsafe impl<O, T: ?Sized> Send for OwningRef<O, T>
+    where O: Send, for<'a> (&'a T): Send {}
+unsafe impl<O, T: ?Sized> Sync for OwningRef<O, T>
+    where O: Sync, for<'a> (&'a T): Sync {}
+
+unsafe impl<O, T: ?Sized> Send for OwningRefMut<O, T>
+    where O: Send, for<'a> (&'a mut T): Send {}
+unsafe impl<O, T: ?Sized> Sync for OwningRefMut<O, T>
+    where O: Sync, for<'a> (&'a mut T): Sync {}
+
+impl Debug for Erased {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f, "<Erased>",)
+    }
+}
+
+impl<O, T: ?Sized> PartialEq for OwningRef<O, T> where T: PartialEq {
+    fn eq(&self, other: &Self) -> bool {
+        (&*self as &T).eq(&*other as &T)
+     }
+}
+
+impl<O, T: ?Sized> Eq for OwningRef<O, T> where T: Eq {}
+
+impl<O, T: ?Sized> PartialOrd for OwningRef<O, T> where T: PartialOrd {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        (&*self as &T).partial_cmp(&*other as &T)
+    }
+}
+
+impl<O, T: ?Sized> Ord for OwningRef<O, T> where T: Ord {
+    fn cmp(&self, other: &Self) -> Ordering {
+        (&*self as &T).cmp(&*other as &T)
+    }
+}
+
+impl<O, T: ?Sized> Hash for OwningRef<O, T> where T: Hash {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (&*self as &T).hash(state);
+    }
+}
+
+impl<O, T: ?Sized> PartialEq for OwningRefMut<O, T> where T: PartialEq {
+    fn eq(&self, other: &Self) -> bool {
+        (&*self as &T).eq(&*other as &T)
+     }
+}
+
+impl<O, T: ?Sized> Eq for OwningRefMut<O, T> where T: Eq {}
+
+impl<O, T: ?Sized> PartialOrd for OwningRefMut<O, T> where T: PartialOrd {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        (&*self as &T).partial_cmp(&*other as &T)
+    }
+}
+
+impl<O, T: ?Sized> Ord for OwningRefMut<O, T> where T: Ord {
+    fn cmp(&self, other: &Self) -> Ordering {
+        (&*self as &T).cmp(&*other as &T)
+    }
+}
+
+impl<O, T: ?Sized> Hash for OwningRefMut<O, T> where T: Hash {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        (&*self as &T).hash(state);
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// std types integration and convenience type defs
+/////////////////////////////////////////////////////////////////////////////
+
+use std::boxed::Box;
+use std::rc::Rc;
+use std::sync::Arc;
+use std::sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard};
+use std::cell::{Ref, RefCell, RefMut};
+
+impl<T: 'static> ToHandle for RefCell<T> {
+    type Handle = Ref<'static, T>;
+    unsafe fn to_handle(x: *const Self) -> Self::Handle { (*x).borrow() }
+}
+
+impl<T: 'static> ToHandleMut for RefCell<T> {
+    type HandleMut = RefMut<'static, T>;
+    unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut { (*x).borrow_mut() }
+}
+
+// NB: Implementing ToHandle{,Mut} for Mutex and RwLock requires a decision
+// about which handle creation to use (i.e. read() vs try_read()) as well as
+// what to do with error results.
+
+/// Typedef of a owning reference that uses a `Box` as the owner.
+pub type BoxRef<T, U = T> = OwningRef<Box<T>, U>;
+/// Typedef of a owning reference that uses a `Vec` as the owner.
+pub type VecRef<T, U = T> = OwningRef<Vec<T>, U>;
+/// Typedef of a owning reference that uses a `String` as the owner.
+pub type StringRef = OwningRef<String, str>;
+
+/// Typedef of a owning reference that uses a `Rc` as the owner.
+pub type RcRef<T, U = T> = OwningRef<Rc<T>, U>;
+/// Typedef of a owning reference that uses a `Arc` as the owner.
+pub type ArcRef<T, U = T> = OwningRef<Arc<T>, U>;
+
+/// Typedef of a owning reference that uses a `Ref` as the owner.
+pub type RefRef<'a, T, U = T> = OwningRef<Ref<'a, T>, U>;
+/// Typedef of a owning reference that uses a `RefMut` as the owner.
+pub type RefMutRef<'a, T, U = T> = OwningRef<RefMut<'a, T>, U>;
+/// Typedef of a owning reference that uses a `MutexGuard` as the owner.
+pub type MutexGuardRef<'a, T, U = T> = OwningRef<MutexGuard<'a, T>, U>;
+/// Typedef of a owning reference that uses a `RwLockReadGuard` as the owner.
+pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef<RwLockReadGuard<'a, T>, U>;
+/// Typedef of a owning reference that uses a `RwLockWriteGuard` as the owner.
+pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
+
+/// Typedef of a mutable owning reference that uses a `Box` as the owner.
+pub type BoxRefMut<T, U = T> = OwningRefMut<Box<T>, U>;
+/// Typedef of a mutable owning reference that uses a `Vec` as the owner.
+pub type VecRefMut<T, U = T> = OwningRefMut<Vec<T>, U>;
+/// Typedef of a mutable owning reference that uses a `String` as the owner.
+pub type StringRefMut = OwningRefMut<String, str>;
+
+/// Typedef of a mutable owning reference that uses a `RefMut` as the owner.
+pub type RefMutRefMut<'a, T, U = T> = OwningRefMut<RefMut<'a, T>, U>;
+/// Typedef of a mutable owning reference that uses a `MutexGuard` as the owner.
+pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut<MutexGuard<'a, T>, U>;
+/// Typedef of a mutable owning reference that uses a `RwLockWriteGuard` as the owner.
+pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
+
+unsafe impl<'a, T: 'a> IntoErased<'a> for Box<T> {
+    type Erased = Box<Erased + 'a>;
+    fn into_erased(self) -> Self::Erased {
+        self
+    }
+}
+unsafe impl<'a, T: 'a> IntoErased<'a> for Rc<T> {
+    type Erased = Rc<Erased + 'a>;
+    fn into_erased(self) -> Self::Erased {
+        self
+    }
+}
+unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
+    type Erased = Arc<Erased + 'a>;
+    fn into_erased(self) -> Self::Erased {
+        self
+    }
+}
+
+unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Box<T> {
+    type Erased = Box<Erased + Send + Sync + 'a>;
+    fn into_erased_send_sync(self) -> Self::Erased {
+        self
+    }
+}
+
+unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
+    type Erased = Arc<Erased + Send + Sync + 'a>;
+    fn into_erased_send_sync(self) -> Self::Erased {
+        self
+    }
+}
+
+/// Typedef of a owning reference that uses an erased `Box` as the owner.
+pub type ErasedBoxRef<U> = OwningRef<Box<Erased>, U>;
+/// Typedef of a owning reference that uses an erased `Rc` as the owner.
+pub type ErasedRcRef<U> = OwningRef<Rc<Erased>, U>;
+/// Typedef of a owning reference that uses an erased `Arc` as the owner.
+pub type ErasedArcRef<U> = OwningRef<Arc<Erased>, U>;
+
+/// Typedef of a mutable owning reference that uses an erased `Box` as the owner.
+pub type ErasedBoxRefMut<U> = OwningRefMut<Box<Erased>, U>;
+
+#[cfg(test)]
+mod tests {
+    mod owning_ref {
+        use super::super::OwningRef;
+        use super::super::{RcRef, BoxRef, Erased, ErasedBoxRef};
+        use std::cmp::{PartialEq, Ord, PartialOrd, Ordering};
+        use std::hash::{Hash, Hasher};
+        use std::collections::hash_map::DefaultHasher;
+        use std::collections::HashMap;
+        use std::rc::Rc;
+
+        #[derive(Debug, PartialEq)]
+        struct Example(u32, String, [u8; 3]);
+        fn example() -> Example {
+            Example(42, "hello world".to_string(), [1, 2, 3])
+        }
+
+        #[test]
+        fn new_deref() {
+            let or: OwningRef<Box<()>, ()> = OwningRef::new(Box::new(()));
+            assert_eq!(&*or, &());
+        }
+
+        #[test]
+        fn into() {
+            let or: OwningRef<Box<()>, ()> = Box::new(()).into();
+            assert_eq!(&*or, &());
+        }
+
+        #[test]
+        fn map_offset_ref() {
+            let or: BoxRef<Example> = Box::new(example()).into();
+            let or: BoxRef<_, u32> = or.map(|x| &x.0);
+            assert_eq!(&*or, &42);
+
+            let or: BoxRef<Example> = Box::new(example()).into();
+            let or: BoxRef<_, u8> = or.map(|x| &x.2[1]);
+            assert_eq!(&*or, &2);
+        }
+
+        #[test]
+        fn map_heap_ref() {
+            let or: BoxRef<Example> = Box::new(example()).into();
+            let or: BoxRef<_, str> = or.map(|x| &x.1[..5]);
+            assert_eq!(&*or, "hello");
+        }
+
+        #[test]
+        fn map_static_ref() {
+            let or: BoxRef<()> = Box::new(()).into();
+            let or: BoxRef<_, str> = or.map(|_| "hello");
+            assert_eq!(&*or, "hello");
+        }
+
+        #[test]
+        fn map_chained() {
+            let or: BoxRef<String> = Box::new(example().1).into();
+            let or: BoxRef<_, str> = or.map(|x| &x[1..5]);
+            let or: BoxRef<_, str> = or.map(|x| &x[..2]);
+            assert_eq!(&*or, "el");
+        }
+
+        #[test]
+        fn map_chained_inference() {
+            let or = BoxRef::new(Box::new(example().1))
+                .map(|x| &x[..5])
+                .map(|x| &x[1..3]);
+            assert_eq!(&*or, "el");
+        }
+
+        #[test]
+        fn owner() {
+            let or: BoxRef<String> = Box::new(example().1).into();
+            let or = or.map(|x| &x[..5]);
+            assert_eq!(&*or, "hello");
+            assert_eq!(&**or.owner(), "hello world");
+        }
+
+        #[test]
+        fn into_inner() {
+            let or: BoxRef<String> = Box::new(example().1).into();
+            let or = or.map(|x| &x[..5]);
+            assert_eq!(&*or, "hello");
+            let s = *or.into_inner();
+            assert_eq!(&s, "hello world");
+        }
+
+        #[test]
+        fn fmt_debug() {
+            let or: BoxRef<String> = Box::new(example().1).into();
+            let or = or.map(|x| &x[..5]);
+            let s = format!("{:?}", or);
+            assert_eq!(&s, "OwningRef { owner: \"hello world\", reference: \"hello\" }");
+        }
+
+        #[test]
+        fn erased_owner() {
+            let o1: BoxRef<Example, str> = BoxRef::new(Box::new(example()))
+                .map(|x| &x.1[..]);
+
+            let o2: BoxRef<String, str> = BoxRef::new(Box::new(example().1))
+                .map(|x| &x[..]);
+
+            let os: Vec<ErasedBoxRef<str>> = vec![o1.erase_owner(), o2.erase_owner()];
+            assert!(os.iter().all(|e| &e[..] == "hello world"));
+        }
+
+        #[test]
+        fn raii_locks() {
+            use super::super::{RefRef, RefMutRef};
+            use std::cell::RefCell;
+            use super::super::{MutexGuardRef, RwLockReadGuardRef, RwLockWriteGuardRef};
+            use std::sync::{Mutex, RwLock};
+
+            {
+                let a = RefCell::new(1);
+                let a = {
+                    let a = RefRef::new(a.borrow());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = RefCell::new(1);
+                let a = {
+                    let a = RefMutRef::new(a.borrow_mut());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = Mutex::new(1);
+                let a = {
+                    let a = MutexGuardRef::new(a.lock().unwrap());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = RwLock::new(1);
+                let a = {
+                    let a = RwLockReadGuardRef::new(a.read().unwrap());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = RwLock::new(1);
+                let a = {
+                    let a = RwLockWriteGuardRef::new(a.write().unwrap());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+        }
+
+        #[test]
+        fn eq() {
+            let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+            assert_eq!(or1.eq(&or2), true);
+        }
+
+        #[test]
+        fn cmp() {
+            let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRef<[u8]> = BoxRef::new(vec![4, 5, 6].into_boxed_slice());
+            assert_eq!(or1.cmp(&or2), Ordering::Less);
+        }
+
+        #[test]
+        fn partial_cmp() {
+            let or1: BoxRef<[u8]> = BoxRef::new(vec![4, 5, 6].into_boxed_slice());
+            let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+            assert_eq!(or1.partial_cmp(&or2), Some(Ordering::Greater));
+        }
+
+        #[test]
+        fn hash() {
+            let mut h1 = DefaultHasher::new();
+            let mut h2 = DefaultHasher::new();
+
+            let or1: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRef<[u8]> = BoxRef::new(vec![1, 2, 3].into_boxed_slice());
+
+            or1.hash(&mut h1);
+            or2.hash(&mut h2);
+
+            assert_eq!(h1.finish(), h2.finish());
+        }
+
+        #[test]
+        fn borrow() {
+            let mut hash = HashMap::new();
+            let     key  = RcRef::<String>::new(Rc::new("foo-bar".to_string())).map(|s| &s[..]);
+
+            hash.insert(key.clone().map(|s| &s[..3]), 42);
+            hash.insert(key.clone().map(|s| &s[4..]), 23);
+
+            assert_eq!(hash.get("foo"), Some(&42));
+            assert_eq!(hash.get("bar"), Some(&23));
+        }
+
+        #[test]
+        fn total_erase() {
+            let a: OwningRef<Vec<u8>, [u8]>
+                = OwningRef::new(vec![]).map(|x| &x[..]);
+            let b: OwningRef<Box<[u8]>, [u8]>
+                = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]);
+
+            let c: OwningRef<Rc<Vec<u8>>, [u8]> = unsafe {a.map_owner(Rc::new)};
+            let d: OwningRef<Rc<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Rc::new)};
+
+            let e: OwningRef<Rc<Erased>, [u8]> = c.erase_owner();
+            let f: OwningRef<Rc<Erased>, [u8]> = d.erase_owner();
+
+            let _g = e.clone();
+            let _h = f.clone();
+        }
+
+        #[test]
+        fn total_erase_box() {
+            let a: OwningRef<Vec<u8>, [u8]>
+                = OwningRef::new(vec![]).map(|x| &x[..]);
+            let b: OwningRef<Box<[u8]>, [u8]>
+                = OwningRef::new(vec![].into_boxed_slice()).map(|x| &x[..]);
+
+            let c: OwningRef<Box<Vec<u8>>, [u8]> = a.map_owner_box();
+            let d: OwningRef<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
+
+            let _e: OwningRef<Box<Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRef<Box<Erased>, [u8]> = d.erase_owner();
+        }
+
+        #[test]
+        fn try_map1() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
+        }
+
+        #[test]
+        fn try_map2() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRef::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
+        }
+    }
+
+    mod owning_handle {
+        use super::super::OwningHandle;
+        use super::super::RcRef;
+        use std::rc::Rc;
+        use std::cell::RefCell;
+        use std::sync::Arc;
+        use std::sync::RwLock;
+
+        #[test]
+        fn owning_handle() {
+            use std::cell::RefCell;
+            let cell = Rc::new(RefCell::new(2));
+            let cell_ref = RcRef::new(cell);
+            let mut handle = OwningHandle::new_with_fn(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
+            assert_eq!(*handle, 2);
+            *handle = 3;
+            assert_eq!(*handle, 3);
+        }
+
+        #[test]
+        fn try_owning_handle_ok() {
+            use std::cell::RefCell;
+            let cell = Rc::new(RefCell::new(2));
+            let cell_ref = RcRef::new(cell);
+            let mut handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| {
+                Ok(unsafe {
+                    x.as_ref()
+                }.unwrap().borrow_mut())
+            }).unwrap();
+            assert_eq!(*handle, 2);
+            *handle = 3;
+            assert_eq!(*handle, 3);
+        }
+
+        #[test]
+        fn try_owning_handle_err() {
+            use std::cell::RefCell;
+            let cell = Rc::new(RefCell::new(2));
+            let cell_ref = RcRef::new(cell);
+            let handle = OwningHandle::try_new::<_, ()>(cell_ref, |x| {
+                if false {
+                    return Ok(unsafe {
+                        x.as_ref()
+                    }.unwrap().borrow_mut())
+                }
+                Err(())
+            });
+            assert!(handle.is_err());
+        }
+
+        #[test]
+        fn nested() {
+            use std::cell::RefCell;
+            use std::sync::{Arc, RwLock};
+
+            let result = {
+                let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString"))));
+                let curr = RcRef::new(complex);
+                let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
+                let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap());
+                assert_eq!(*curr, "someString");
+                *curr = "someOtherString";
+                curr
+            };
+            assert_eq!(*result, "someOtherString");
+        }
+
+        #[test]
+        fn owning_handle_safe() {
+            use std::cell::RefCell;
+            let cell = Rc::new(RefCell::new(2));
+            let cell_ref = RcRef::new(cell);
+            let handle = OwningHandle::new(cell_ref);
+            assert_eq!(*handle, 2);
+        }
+
+        #[test]
+        fn owning_handle_mut_safe() {
+            use std::cell::RefCell;
+            let cell = Rc::new(RefCell::new(2));
+            let cell_ref = RcRef::new(cell);
+            let mut handle = OwningHandle::new_mut(cell_ref);
+            assert_eq!(*handle, 2);
+            *handle = 3;
+            assert_eq!(*handle, 3);
+        }
+
+        #[test]
+        fn owning_handle_safe_2() {
+            let result = {
+                let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString"))));
+                let curr = RcRef::new(complex);
+                let curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
+                let mut curr = OwningHandle::new_with_fn(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap());
+                assert_eq!(*curr, "someString");
+                *curr = "someOtherString";
+                curr
+            };
+            assert_eq!(*result, "someOtherString");
+        }
+    }
+
+    mod owning_ref_mut {
+        use super::super::{OwningRefMut, BoxRefMut, Erased, ErasedBoxRefMut};
+        use super::super::BoxRef;
+        use std::cmp::{PartialEq, Ord, PartialOrd, Ordering};
+        use std::hash::{Hash, Hasher};
+        use std::collections::hash_map::DefaultHasher;
+        use std::collections::HashMap;
+
+        #[derive(Debug, PartialEq)]
+        struct Example(u32, String, [u8; 3]);
+        fn example() -> Example {
+            Example(42, "hello world".to_string(), [1, 2, 3])
+        }
+
+        #[test]
+        fn new_deref() {
+            let or: OwningRefMut<Box<()>, ()> = OwningRefMut::new(Box::new(()));
+            assert_eq!(&*or, &());
+        }
+
+        #[test]
+        fn new_deref_mut() {
+            let mut or: OwningRefMut<Box<()>, ()> = OwningRefMut::new(Box::new(()));
+            assert_eq!(&mut *or, &mut ());
+        }
+
+        #[test]
+        fn mutate() {
+            let mut or: OwningRefMut<Box<usize>, usize> = OwningRefMut::new(Box::new(0));
+            assert_eq!(&*or, &0);
+            *or = 1;
+            assert_eq!(&*or, &1);
+        }
+
+        #[test]
+        fn into() {
+            let or: OwningRefMut<Box<()>, ()> = Box::new(()).into();
+            assert_eq!(&*or, &());
+        }
+
+        #[test]
+        fn map_offset_ref() {
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRef<_, u32> = or.map(|x| &mut x.0);
+            assert_eq!(&*or, &42);
+
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRef<_, u8> = or.map(|x| &mut x.2[1]);
+            assert_eq!(&*or, &2);
+        }
+
+        #[test]
+        fn map_heap_ref() {
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRef<_, str> = or.map(|x| &mut x.1[..5]);
+            assert_eq!(&*or, "hello");
+        }
+
+        #[test]
+        fn map_static_ref() {
+            let or: BoxRefMut<()> = Box::new(()).into();
+            let or: BoxRef<_, str> = or.map(|_| "hello");
+            assert_eq!(&*or, "hello");
+        }
+
+        #[test]
+        fn map_mut_offset_ref() {
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRefMut<_, u32> = or.map_mut(|x| &mut x.0);
+            assert_eq!(&*or, &42);
+
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRefMut<_, u8> = or.map_mut(|x| &mut x.2[1]);
+            assert_eq!(&*or, &2);
+        }
+
+        #[test]
+        fn map_mut_heap_ref() {
+            let or: BoxRefMut<Example> = Box::new(example()).into();
+            let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x.1[..5]);
+            assert_eq!(&*or, "hello");
+        }
+
+        #[test]
+        fn map_mut_static_ref() {
+            static mut MUT_S: [u8; 5] = *b"hello";
+
+            let mut_s: &'static mut [u8] = unsafe { &mut MUT_S };
+
+            let or: BoxRefMut<()> = Box::new(()).into();
+            let or: BoxRefMut<_, [u8]> = or.map_mut(move |_| mut_s);
+            assert_eq!(&*or, b"hello");
+        }
+
+        #[test]
+        fn map_mut_chained() {
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x[1..5]);
+            let or: BoxRefMut<_, str> = or.map_mut(|x| &mut x[..2]);
+            assert_eq!(&*or, "el");
+        }
+
+        #[test]
+        fn map_chained_inference() {
+            let or = BoxRefMut::new(Box::new(example().1))
+                .map_mut(|x| &mut x[..5])
+                .map_mut(|x| &mut x[1..3]);
+            assert_eq!(&*or, "el");
+        }
+
+        #[test]
+        fn try_map_mut() {
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or: Result<BoxRefMut<_, str>, ()> = or.try_map_mut(|x| Ok(&mut x[1..5]));
+            assert_eq!(&*or.unwrap(), "ello");
+
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or: Result<BoxRefMut<_, str>, ()> = or.try_map_mut(|_| Err(()));
+            assert!(or.is_err());
+        }
+
+        #[test]
+        fn owner() {
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or = or.map_mut(|x| &mut x[..5]);
+            assert_eq!(&*or, "hello");
+            assert_eq!(&**or.owner(), "hello world");
+        }
+
+        #[test]
+        fn into_inner() {
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or = or.map_mut(|x| &mut x[..5]);
+            assert_eq!(&*or, "hello");
+            let s = *or.into_inner();
+            assert_eq!(&s, "hello world");
+        }
+
+        #[test]
+        fn fmt_debug() {
+            let or: BoxRefMut<String> = Box::new(example().1).into();
+            let or = or.map_mut(|x| &mut x[..5]);
+            let s = format!("{:?}", or);
+            assert_eq!(&s,
+                       "OwningRefMut { owner: \"hello world\", reference: \"hello\" }");
+        }
+
+        #[test]
+        fn erased_owner() {
+            let o1: BoxRefMut<Example, str> = BoxRefMut::new(Box::new(example()))
+                .map_mut(|x| &mut x.1[..]);
+
+            let o2: BoxRefMut<String, str> = BoxRefMut::new(Box::new(example().1))
+                .map_mut(|x| &mut x[..]);
+
+            let os: Vec<ErasedBoxRefMut<str>> = vec![o1.erase_owner(), o2.erase_owner()];
+            assert!(os.iter().all(|e| &e[..] == "hello world"));
+        }
+
+        #[test]
+        fn raii_locks() {
+            use super::super::RefMutRefMut;
+            use std::cell::RefCell;
+            use super::super::{MutexGuardRefMut, RwLockWriteGuardRefMut};
+            use std::sync::{Mutex, RwLock};
+
+            {
+                let a = RefCell::new(1);
+                let a = {
+                    let a = RefMutRefMut::new(a.borrow_mut());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = Mutex::new(1);
+                let a = {
+                    let a = MutexGuardRefMut::new(a.lock().unwrap());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+            {
+                let a = RwLock::new(1);
+                let a = {
+                    let a = RwLockWriteGuardRefMut::new(a.write().unwrap());
+                    assert_eq!(*a, 1);
+                    a
+                };
+                assert_eq!(*a, 1);
+                drop(a);
+            }
+        }
+
+        #[test]
+        fn eq() {
+            let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+            assert_eq!(or1.eq(&or2), true);
+        }
+
+        #[test]
+        fn cmp() {
+            let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![4, 5, 6].into_boxed_slice());
+            assert_eq!(or1.cmp(&or2), Ordering::Less);
+        }
+
+        #[test]
+        fn partial_cmp() {
+            let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![4, 5, 6].into_boxed_slice());
+            let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+            assert_eq!(or1.partial_cmp(&or2), Some(Ordering::Greater));
+        }
+
+        #[test]
+        fn hash() {
+            let mut h1 = DefaultHasher::new();
+            let mut h2 = DefaultHasher::new();
+
+            let or1: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+            let or2: BoxRefMut<[u8]> = BoxRefMut::new(vec![1, 2, 3].into_boxed_slice());
+
+            or1.hash(&mut h1);
+            or2.hash(&mut h2);
+
+            assert_eq!(h1.finish(), h2.finish());
+        }
+
+        #[test]
+        fn borrow() {
+            let mut hash = HashMap::new();
+            let     key1 = BoxRefMut::<String>::new(Box::new("foo".to_string())).map(|s| &s[..]);
+            let     key2 = BoxRefMut::<String>::new(Box::new("bar".to_string())).map(|s| &s[..]);
+
+            hash.insert(key1, 42);
+            hash.insert(key2, 23);
+
+            assert_eq!(hash.get("foo"), Some(&42));
+            assert_eq!(hash.get("bar"), Some(&23));
+        }
+
+        #[test]
+        fn total_erase() {
+            let a: OwningRefMut<Vec<u8>, [u8]>
+                = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]);
+            let b: OwningRefMut<Box<[u8]>, [u8]>
+                = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]);
+
+            let c: OwningRefMut<Box<Vec<u8>>, [u8]> = unsafe {a.map_owner(Box::new)};
+            let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = unsafe {b.map_owner(Box::new)};
+
+            let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
+        }
+
+        #[test]
+        fn total_erase_box() {
+            let a: OwningRefMut<Vec<u8>, [u8]>
+                = OwningRefMut::new(vec![]).map_mut(|x| &mut x[..]);
+            let b: OwningRefMut<Box<[u8]>, [u8]>
+                = OwningRefMut::new(vec![].into_boxed_slice()).map_mut(|x| &mut x[..]);
+
+            let c: OwningRefMut<Box<Vec<u8>>, [u8]> = a.map_owner_box();
+            let d: OwningRefMut<Box<Box<[u8]>>, [u8]> = b.map_owner_box();
+
+            let _e: OwningRefMut<Box<Erased>, [u8]> = c.erase_owner();
+            let _f: OwningRefMut<Box<Erased>, [u8]> = d.erase_owner();
+        }
+
+        #[test]
+        fn try_map1() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_ok();
+        }
+
+        #[test]
+        fn try_map2() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRefMut::new(y).try_map_mut(|x| x.downcast_mut::<i32>().ok_or(())).is_err();
+        }
+
+        #[test]
+        fn try_map3() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_ok();
+        }
+
+        #[test]
+        fn try_map4() {
+            use std::any::Any;
+
+            let x = Box::new(123_i32);
+            let y: Box<Any> = x;
+
+            OwningRefMut::new(y).try_map(|x| x.downcast_ref::<i32>().ok_or(())).is_err();
+        }
+
+        #[test]
+        fn into_owning_ref() {
+            use super::super::BoxRef;
+
+            let or: BoxRefMut<()> = Box::new(()).into();
+            let or: BoxRef<()> = or.into();
+            assert_eq!(&*or, &());
+        }
+
+        struct Foo {
+            u: u32,
+        }
+        struct Bar {
+            f: Foo,
+        }
+
+        #[test]
+        fn ref_mut() {
+            use std::cell::RefCell;
+
+            let a = RefCell::new(Bar { f: Foo { u: 42 } });
+            let mut b = OwningRefMut::new(a.borrow_mut());
+            assert_eq!(b.f.u, 42);
+            b.f.u = 43;
+            let mut c = b.map_mut(|x| &mut x.f);
+            assert_eq!(c.u, 43);
+            c.u = 44;
+            let mut d = c.map_mut(|x| &mut x.u);
+            assert_eq!(*d, 44);
+            *d = 45;
+            assert_eq!(*d, 45);
+        }
+    }
+}
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
new file mode 100644
index 0000000000000..b1ab4eaa06924
--- /dev/null
+++ b/src/librustc_data_structures/sync.rs
@@ -0,0 +1,403 @@
+// Copyright 2017 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.
+
+//! This mdoule defines types which are thread safe if cfg!(parallel_queries) is true.
+//!
+//! `Lrc` is an alias of either Rc or Arc.
+//!
+//! `Lock` is a mutex.
+//! It internally uses `parking_lot::Mutex` if cfg!(parallel_queries) is true,
+//! `RefCell` otherwise.
+//!
+//! `RwLock` is a read-write lock.
+//! It internally uses `parking_lot::RwLock` if cfg!(parallel_queries) is true,
+//! `RefCell` otherwise.
+//!
+//! `LockCell` is a thread safe version of `Cell`, with `set` and `get` operations.
+//! It can never deadlock. It uses `Cell` when
+//! cfg!(parallel_queries) is false, otherwise it is a `Lock`.
+//!
+//! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false.
+//!
+//! `rustc_global!` gives us a way to declare variables which are intended to be
+//! global for the current rustc session. This currently maps to thread-locals,
+//! since rustdoc uses the rustc libraries in multiple threads.
+//! These globals should eventually be moved into the `Session` structure.
+//!
+//! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync
+//! depending on the value of cfg!(parallel_queries).
+
+use std::cmp::Ordering;
+use std::fmt::Debug;
+use std::fmt::Formatter;
+use std::fmt;
+use owning_ref::{Erased, OwningRef};
+
+cfg_if! {
+    if #[cfg(not(parallel_queries))] {
+        pub auto trait Send {}
+        pub auto trait Sync {}
+
+        impl<T: ?Sized> Send for T {}
+        impl<T: ?Sized> Sync for T {}
+
+        #[macro_export]
+        macro_rules! rustc_erase_owner {
+            ($v:expr) => {
+                $v.erase_owner()
+            }
+        }
+
+        pub type MetadataRef = OwningRef<Box<Erased>, [u8]>;
+
+        pub use std::rc::Rc as Lrc;
+        pub use std::cell::Ref as ReadGuard;
+        pub use std::cell::RefMut as WriteGuard;
+        pub use std::cell::RefMut as LockGuard;
+
+        pub use std::cell::RefCell as RwLock;
+        use std::cell::RefCell as InnerLock;
+
+        use std::cell::Cell;
+
+        #[derive(Debug)]
+        pub struct MTLock<T>(T);
+
+        impl<T> MTLock<T> {
+            #[inline(always)]
+            pub fn new(inner: T) -> Self {
+                MTLock(inner)
+            }
+
+            #[inline(always)]
+            pub fn into_inner(self) -> T {
+                self.0
+            }
+
+            #[inline(always)]
+            pub fn get_mut(&mut self) -> &mut T {
+                &mut self.0
+            }
+
+            #[inline(always)]
+            pub fn lock(&self) -> &T {
+                &self.0
+            }
+
+            #[inline(always)]
+            pub fn borrow(&self) -> &T {
+                &self.0
+            }
+
+            #[inline(always)]
+            pub fn borrow_mut(&self) -> &T {
+                &self.0
+            }
+        }
+
+        // FIXME: Probably a bad idea (in the threaded case)
+        impl<T: Clone> Clone for MTLock<T> {
+            #[inline]
+            fn clone(&self) -> Self {
+                MTLock(self.0.clone())
+            }
+        }
+
+        pub struct LockCell<T>(Cell<T>);
+
+        impl<T> LockCell<T> {
+            #[inline(always)]
+            pub fn new(inner: T) -> Self {
+                LockCell(Cell::new(inner))
+            }
+
+            #[inline(always)]
+            pub fn into_inner(self) -> T {
+                self.0.into_inner()
+            }
+
+            #[inline(always)]
+            pub fn set(&self, new_inner: T) {
+                self.0.set(new_inner);
+            }
+
+            #[inline(always)]
+            pub fn get(&self) -> T where T: Copy {
+                self.0.get()
+            }
+
+            #[inline(always)]
+            pub fn set_mut(&mut self, new_inner: T) {
+                self.0.set(new_inner);
+            }
+
+            #[inline(always)]
+            pub fn get_mut(&mut self) -> T where T: Copy {
+                self.0.get()
+            }
+        }
+
+        impl<T> LockCell<Option<T>> {
+            #[inline(always)]
+            pub fn take(&self) -> Option<T> {
+                unsafe { (*self.0.as_ptr()).take() }
+            }
+        }
+    } else {
+        pub use std::marker::Send as Send;
+        pub use std::marker::Sync as Sync;
+
+        pub use parking_lot::RwLockReadGuard as ReadGuard;
+        pub use parking_lot::RwLockWriteGuard as WriteGuard;
+
+        pub use parking_lot::MutexGuard as LockGuard;
+
+        use parking_lot;
+
+        pub use std::sync::Arc as Lrc;
+
+        pub use self::Lock as MTLock;
+
+        use parking_lot::Mutex as InnerLock;
+
+        pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>;
+
+        /// This makes locks panic if they are already held.
+        /// It is only useful when you are running in a single thread
+        const ERROR_CHECKING: bool = false;
+
+        #[macro_export]
+        macro_rules! rustc_erase_owner {
+            ($v:expr) => {{
+                let v = $v;
+                ::rustc_data_structures::sync::assert_send_sync_val(&v);
+                v.erase_send_sync_owner()
+            }}
+        }
+
+        pub struct LockCell<T>(Lock<T>);
+
+        impl<T> LockCell<T> {
+            #[inline(always)]
+            pub fn new(inner: T) -> Self {
+                LockCell(Lock::new(inner))
+            }
+
+            #[inline(always)]
+            pub fn into_inner(self) -> T {
+                self.0.into_inner()
+            }
+
+            #[inline(always)]
+            pub fn set(&self, new_inner: T) {
+                *self.0.lock() = new_inner;
+            }
+
+            #[inline(always)]
+            pub fn get(&self) -> T where T: Copy {
+                *self.0.lock()
+            }
+
+            #[inline(always)]
+            pub fn set_mut(&mut self, new_inner: T) {
+                *self.0.get_mut() = new_inner;
+            }
+
+            #[inline(always)]
+            pub fn get_mut(&mut self) -> T where T: Copy {
+                *self.0.get_mut()
+            }
+        }
+
+        impl<T> LockCell<Option<T>> {
+            #[inline(always)]
+            pub fn take(&self) -> Option<T> {
+                self.0.lock().take()
+            }
+        }
+
+        #[derive(Debug)]
+        pub struct RwLock<T>(parking_lot::RwLock<T>);
+
+        impl<T> RwLock<T> {
+            #[inline(always)]
+            pub fn new(inner: T) -> Self {
+                RwLock(parking_lot::RwLock::new(inner))
+            }
+
+            #[inline(always)]
+            pub fn borrow(&self) -> ReadGuard<T> {
+                if ERROR_CHECKING {
+                    self.0.try_read().expect("lock was already held")
+                } else {
+                    self.0.read()
+                }
+            }
+
+            #[inline(always)]
+            pub fn borrow_mut(&self) -> WriteGuard<T> {
+                if ERROR_CHECKING {
+                    self.0.try_write().expect("lock was already held")
+                } else {
+                    self.0.write()
+                }
+            }
+        }
+
+        // FIXME: Probably a bad idea
+        impl<T: Clone> Clone for RwLock<T> {
+            #[inline]
+            fn clone(&self) -> Self {
+                RwLock::new(self.borrow().clone())
+            }
+        }
+    }
+}
+
+pub fn assert_sync<T: ?Sized + Sync>() {}
+pub fn assert_send_sync_val<T: ?Sized + Sync + Send>(_t: &T) {}
+
+#[macro_export]
+#[allow_internal_unstable]
+macro_rules! rustc_global {
+    // empty (base case for the recursion)
+    () => {};
+
+    // process multiple declarations
+    ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
+        thread_local!($(#[$attr])* $vis static $name: $t = $init);
+        rustc_global!($($rest)*);
+    );
+
+    // handle a single declaration
+    ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => (
+        thread_local!($(#[$attr])* $vis static $name: $t = $init);
+    );
+}
+
+#[macro_export]
+macro_rules! rustc_access_global {
+    ($name:path, $callback:expr) => {
+        $name.with($callback)
+    }
+}
+
+impl<T: Copy + Debug> Debug for LockCell<T> {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        f.debug_struct("LockCell")
+            .field("value", &self.get())
+            .finish()
+    }
+}
+
+impl<T:Default> Default for LockCell<T> {
+    /// Creates a `LockCell<T>`, with the `Default` value for T.
+    #[inline]
+    fn default() -> LockCell<T> {
+        LockCell::new(Default::default())
+    }
+}
+
+impl<T:PartialEq + Copy> PartialEq for LockCell<T> {
+    #[inline]
+    fn eq(&self, other: &LockCell<T>) -> bool {
+        self.get() == other.get()
+    }
+}
+
+impl<T:Eq + Copy> Eq for LockCell<T> {}
+
+impl<T:PartialOrd + Copy> PartialOrd for LockCell<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &LockCell<T>) -> Option<Ordering> {
+        self.get().partial_cmp(&other.get())
+    }
+
+    #[inline]
+    fn lt(&self, other: &LockCell<T>) -> bool {
+        self.get() < other.get()
+    }
+
+    #[inline]
+    fn le(&self, other: &LockCell<T>) -> bool {
+        self.get() <= other.get()
+    }
+
+    #[inline]
+    fn gt(&self, other: &LockCell<T>) -> bool {
+        self.get() > other.get()
+    }
+
+    #[inline]
+    fn ge(&self, other: &LockCell<T>) -> bool {
+        self.get() >= other.get()
+    }
+}
+
+impl<T:Ord + Copy> Ord for LockCell<T> {
+    #[inline]
+    fn cmp(&self, other: &LockCell<T>) -> Ordering {
+        self.get().cmp(&other.get())
+    }
+}
+
+#[derive(Debug)]
+pub struct Lock<T>(InnerLock<T>);
+
+impl<T> Lock<T> {
+    #[inline(always)]
+    pub fn new(inner: T) -> Self {
+        Lock(InnerLock::new(inner))
+    }
+
+    #[inline(always)]
+    pub fn into_inner(self) -> T {
+        self.0.into_inner()
+    }
+
+    #[inline(always)]
+    pub fn get_mut(&mut self) -> &mut T {
+        self.0.get_mut()
+    }
+
+    #[cfg(parallel_queries)]
+    #[inline(always)]
+    pub fn lock(&self) -> LockGuard<T> {
+        if ERROR_CHECKING {
+            self.0.try_lock().expect("lock was already held")
+        } else {
+            self.0.lock()
+        }
+    }
+
+    #[cfg(not(parallel_queries))]
+    #[inline(always)]
+    pub fn lock(&self) -> LockGuard<T> {
+        self.0.borrow_mut()
+    }
+
+    #[inline(always)]
+    pub fn borrow(&self) -> LockGuard<T> {
+        self.lock()
+    }
+
+    #[inline(always)]
+    pub fn borrow_mut(&self) -> LockGuard<T> {
+        self.lock()
+    }
+}
+
+// FIXME: Probably a bad idea
+impl<T: Clone> Clone for Lock<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        Lock::new(self.borrow().clone())
+    }
+}
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index d6155f53485e3..04c0f9b35184e 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -12,7 +12,6 @@ crate-type = ["dylib"]
 arena = { path = "../libarena" }
 graphviz = { path = "../libgraphviz" }
 log = { version = "0.3", features = ["release_max_level_info"] }
-owning_ref = "0.3.3"
 env_logger = { version = "0.4", default-features = false }
 rustc = { path = "../librustc" }
 rustc_allocator = { path = "../librustc_allocator" }
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 40b75be36fefb..3d61bc102e251 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -11,7 +11,6 @@ crate-type = ["dylib"]
 [dependencies]
 flate2 = "0.2"
 log = "0.3"
-owning_ref = "0.3.3"
 proc_macro = { path = "../libproc_macro" }
 rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 3a4ba6768a716..87e41cae60d66 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -24,7 +24,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
 
 use std::cell::{RefCell, Cell};
 use std::rc::Rc;
-use owning_ref::ErasedBoxRef;
+use rustc_data_structures::owning_ref::ErasedBoxRef;
 use syntax::{ast, attr};
 use syntax::ext::base::SyntaxExtension;
 use syntax::symbol::Symbol;
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 6c1ca36232307..a65ddcecf8874 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -31,7 +31,6 @@ extern crate syntax;
 extern crate syntax_pos;
 extern crate flate2;
 extern crate serialize as rustc_serialize; // used by deriving
-extern crate owning_ref;
 extern crate rustc_errors as errors;
 extern crate syntax_ext;
 extern crate proc_macro;
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 8abccb503d6fa..90c469eea843d 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -243,7 +243,7 @@ use std::path::{Path, PathBuf};
 use std::time::Instant;
 
 use flate2::read::DeflateDecoder;
-use owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
 
 pub struct CrateMismatch {
     path: PathBuf,
diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml
index d8318ea808221..131cf59a57184 100644
--- a/src/librustc_trans/Cargo.toml
+++ b/src/librustc_trans/Cargo.toml
@@ -15,7 +15,6 @@ flate2 = "0.2"
 jobserver = "0.1.5"
 log = "0.3"
 num_cpus = "1.0"
-owning_ref = "0.3.3"
 rustc = { path = "../librustc" }
 rustc-demangle = "0.1.4"
 rustc_allocator = { path = "../librustc_allocator" }
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 3c2e56bf2a127..f6cc1215699c6 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -40,7 +40,6 @@ use syntax_pos::symbol::Symbol;
 extern crate bitflags;
 extern crate flate2;
 extern crate libc;
-extern crate owning_ref;
 #[macro_use] extern crate rustc;
 extern crate jobserver;
 extern crate num_cpus;
diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs
index 883808c59091a..d57624da0c68d 100644
--- a/src/librustc_trans/metadata.rs
+++ b/src/librustc_trans/metadata.rs
@@ -15,7 +15,7 @@ use llvm;
 use llvm::{False, ObjectFile, mk_section_iter};
 use llvm::archive_ro::ArchiveRO;
 
-use owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
 use std::path::Path;
 use std::ptr;
 use std::slice;
diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml
index 7d9d7cea9335d..cab44778baabe 100644
--- a/src/librustc_trans_utils/Cargo.toml
+++ b/src/librustc_trans_utils/Cargo.toml
@@ -12,7 +12,6 @@ test = false
 [dependencies]
 ar = "0.3.0"
 flate2 = "0.2"
-owning_ref = "0.3.3"
 log = "0.3"
 
 syntax = { path = "../libsyntax" }
diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs
index d6f8707b8747a..3a42462e41e56 100644
--- a/src/librustc_trans_utils/lib.rs
+++ b/src/librustc_trans_utils/lib.rs
@@ -29,7 +29,6 @@
 
 extern crate ar;
 extern crate flate2;
-extern crate owning_ref;
 #[macro_use]
 extern crate log;
 
diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs
index 645898601614b..800c3063c025c 100644
--- a/src/librustc_trans_utils/trans_crate.rs
+++ b/src/librustc_trans_utils/trans_crate.rs
@@ -28,7 +28,7 @@ use std::fs::File;
 use std::path::Path;
 use std::sync::mpsc;
 
-use owning_ref::{ErasedBoxRef, OwningRef};
+use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef};
 use ar::{Archive, Builder, Header};
 use flate2::Compression;
 use flate2::write::DeflateEncoder;
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 3fd844f326184..61d71986b03eb 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -56,6 +56,7 @@ fn filter_dirs(path: &Path) -> bool {
         "src/llvm",
         "src/libbacktrace",
         "src/libcompiler_builtins",
+        "src/librustc_data_structures/owning_ref",
         "src/compiler-rt",
         "src/liblibc",
         "src/vendor",