about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-05-13 14:58:29 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-05-13 17:24:07 -0700
commitcbc31df4fc084b47a5c6456df2efb6e28b82a7da (patch)
treed978963435cc73d848ff8b936e9b0dba050b482b /src/libstd
parentcb115ac2d4f57d8b590c8d46d8f9e2958ed9a527 (diff)
downloadrust-cbc31df4fc084b47a5c6456df2efb6e28b82a7da.tar.gz
rust-cbc31df4fc084b47a5c6456df2efb6e28b82a7da.zip
std: Move the owned module from core to std
The compiler was updated to recognize that implementations for ty_uniq(..) are
allowed if the Box lang item is located in the current crate. This enforces the
idea that libcore cannot allocated, and moves all related trait implementations
from libcore to libstd.

This is a breaking change in that the AnyOwnExt trait has moved from the any
module to the owned module. Any previous users of std::any::AnyOwnExt should now
use std::owned::AnyOwnExt instead. This was done because the trait is intended
for Box traits and only Box traits.

[breaking-change]
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/lib.rs8
-rw-r--r--src/libstd/owned.rs101
-rw-r--r--src/libstd/rt/task.rs3
-rw-r--r--src/libstd/task.rs5
4 files changed, 111 insertions, 6 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 34ed7933c39..a37f9a516fd 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -133,14 +133,16 @@ extern crate core;
 #[cfg(test)] pub use ops = realstd::ops;
 #[cfg(test)] pub use cmp = realstd::cmp;
 #[cfg(test)] pub use ty = realstd::ty;
-#[cfg(test)] pub use owned = realstd::owned;
+#[cfg(not(stage0), test)] pub use owned = realstd::owned;
 
 #[cfg(not(test))] pub use cmp = core::cmp;
 #[cfg(not(test))] pub use kinds = core::kinds;
 #[cfg(not(test))] pub use ops = core::ops;
-#[cfg(not(test))] pub use owned = core::owned;
 #[cfg(not(test))] pub use ty = core::ty;
 
+#[cfg(stage0, test)] pub use owned = realstd::owned;
+#[cfg(stage0, not(test))] pub use owned = core::owned;
+
 pub use core::any;
 pub use core::bool;
 pub use core::cell;
@@ -207,6 +209,8 @@ pub mod ascii;
 
 pub mod rc;
 pub mod gc;
+#[cfg(not(stage0), not(test))]
+pub mod owned;
 
 /* Common traits */
 
diff --git a/src/libstd/owned.rs b/src/libstd/owned.rs
new file mode 100644
index 00000000000..3af12c5154c
--- /dev/null
+++ b/src/libstd/owned.rs
@@ -0,0 +1,101 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Operations on unique pointer types
+
+use any::{Any, AnyRefExt};
+use clone::Clone;
+use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering};
+use default::Default;
+use intrinsics;
+use mem;
+use raw::TraitObject;
+use result::{Ok, Err, Result};
+
+/// A value that represents the global exchange heap. This is the default
+/// place that the `box` keyword allocates into when no place is supplied.
+///
+/// The following two examples are equivalent:
+///
+///     let foo = box(HEAP) Bar::new(...);
+///     let foo = box Bar::new(...);
+#[lang="exchange_heap"]
+pub static HEAP: () = ();
+
+/// A type that represents a uniquely-owned value.
+#[lang="owned_box"]
+pub struct Box<T>(*T);
+
+impl<T: Default> Default for Box<T> {
+    fn default() -> Box<T> { box Default::default() }
+}
+
+impl<T: Clone> Clone for Box<T> {
+    /// Return a copy of the owned box.
+    #[inline]
+    fn clone(&self) -> Box<T> { box {(**self).clone()} }
+
+    /// Perform copy-assignment from `source` by reusing the existing allocation.
+    #[inline]
+    fn clone_from(&mut self, source: &Box<T>) {
+        (**self).clone_from(&(**source));
+    }
+}
+
+// box pointers
+impl<T:Eq> Eq for Box<T> {
+    #[inline]
+    fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
+    #[inline]
+    fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
+}
+impl<T:Ord> Ord for Box<T> {
+    #[inline]
+    fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
+    #[inline]
+    fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
+    #[inline]
+    fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
+    #[inline]
+    fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
+}
+impl<T: TotalOrd> TotalOrd for Box<T> {
+    #[inline]
+    fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
+}
+impl<T: TotalEq> TotalEq for Box<T> {}
+
+/// Extension methods for an owning `Any` trait object
+pub trait AnyOwnExt {
+    /// Returns the boxed value if it is of type `T`, or
+    /// `Err(Self)` if it isn't.
+    fn move<T: 'static>(self) -> Result<Box<T>, Self>;
+}
+
+impl AnyOwnExt for Box<Any> {
+    #[inline]
+    fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
+        if self.is::<T>() {
+            unsafe {
+                // Get the raw representation of the trait object
+                let to: TraitObject =
+                    *mem::transmute::<&Box<Any>, &TraitObject>(&self);
+
+                // Prevent destructor on self being run
+                intrinsics::forget(self);
+
+                // Extract the data pointer
+                Ok(mem::transmute(to.data))
+            }
+        } else {
+            Err(self)
+        }
+    }
+}
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index cd0445056b2..31a20145306 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -13,7 +13,6 @@
 //! local storage, and logging. Even a 'freestanding' Rust would likely want
 //! to implement this.
 
-use any::AnyOwnExt;
 use cleanup;
 use clone::Clone;
 use comm::Sender;
@@ -24,7 +23,7 @@ use local_data;
 use mem;
 use ops::Drop;
 use option::{Option, Some, None};
-use owned::Box;
+use owned::{AnyOwnExt, Box};
 use prelude::drop;
 use result::{Result, Ok, Err};
 use rt::Runtime;
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index 2f7b31ae31d..7fb61c29112 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -47,10 +47,11 @@ use rt::local::Local;
 use rt::task::Task;
 use str::{Str, SendStr, IntoMaybeOwned};
 
-#[cfg(test)] use any::{AnyOwnExt, AnyRefExt};
+#[cfg(test)] use any::AnyRefExt;
+#[cfg(test)] use owned::AnyOwnExt;
+#[cfg(test)] use realstd::result::ResultUnwrap;
 #[cfg(test)] use result;
 #[cfg(test)] use str::StrAllocating;
-#[cfg(test)] use realstd::result::ResultUnwrap;
 
 /// Indicates the manner in which a task exited.
 ///