diff --git a/src/libcore/any.rs b/src/libcore/any.rs index b0227fd60bfeb..70cd46dcfa2b4 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -22,11 +22,8 @@ use mem::{transmute, transmute_copy}; use option::{Option, Some, None}; -use owned::Box; use raw::TraitObject; -use result::{Result, Ok, Err}; use intrinsics::TypeId; -use intrinsics; /// A type with no inhabitants pub enum Void { } @@ -117,38 +114,11 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any { } } -/// 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(self) -> Result, Self>; -} - -impl AnyOwnExt for Box { - #[inline] - fn move(self) -> Result, Box> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Prevent destructor on self being run - intrinsics::forget(self); - - // Extract the data pointer - Ok(transmute(to.data)) - } - } else { - Err(self) - } - } -} - #[cfg(test)] mod tests { use prelude::*; use super::*; - use owned::Box; + use realstd::owned::{Box, AnyOwnExt}; use realstd::str::StrAllocating; #[deriving(Eq, Show)] @@ -253,6 +223,8 @@ mod tests { #[test] fn any_move() { + use realstd::any::Any; + use realstd::result::{Ok, Err}; let a = box 8u as Box; let b = box Test as Box; diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 06cbaf1981280..cd66beabc12de 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -21,8 +21,6 @@ the `clone` method. */ -use owned::Box; - /// A common trait for cloning an object. pub trait Clone { /// Returns a copy of the value. The contents of owned pointers @@ -41,18 +39,6 @@ pub trait Clone { } } -impl Clone for Box { - /// Return a copy of the owned box. - #[inline] - fn clone(&self) -> Box { box {(**self).clone()} } - - /// Perform copy-assignment from `source` by reusing the existing allocation. - #[inline] - fn clone_from(&mut self, source: &Box) { - (**self).clone_from(&(**source)); - } -} - impl Clone for @T { /// Return a shallow copy of the managed box. #[inline] @@ -129,12 +115,22 @@ extern_fn_clone!(A, B, C, D, E, F, G, H) #[cfg(test)] mod test { use prelude::*; - use owned::Box; + use realstd::owned::Box; + + fn realclone(t: &T) -> T { + use realstd::clone::Clone; + t.clone() + } + + fn realclone_from(t1: &mut T, t2: &T) { + use realstd::clone::Clone; + t1.clone_from(t2) + } #[test] fn test_owned_clone() { let a = box 5i; - let b: Box = a.clone(); + let b: Box = realclone(&a); assert_eq!(a, b); } @@ -157,7 +153,7 @@ mod test { fn test_clone_from() { let a = box 5; let mut b = box 10; - b.clone_from(&a); + realclone_from(&mut b, &a); assert_eq!(*b, 5); } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index af611cd94e506..f2b1c1cd4cde6 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -193,7 +193,6 @@ pub fn max(v1: T, v2: T) -> T { #[cfg(not(test))] mod impls { use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering}; - use owned::Box; // & pointers impl<'a, T: Eq> Eq for &'a T { @@ -240,29 +239,6 @@ mod impls { fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) } } impl TotalEq for @T {} - - // box pointers - impl Eq for Box { - #[inline] - fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } - #[inline] - fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } - } - impl Ord for Box { - #[inline] - fn lt(&self, other: &Box) -> bool { *(*self) < *(*other) } - #[inline] - fn le(&self, other: &Box) -> bool { *(*self) <= *(*other) } - #[inline] - fn ge(&self, other: &Box) -> bool { *(*self) >= *(*other) } - #[inline] - fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } - } - impl TotalOrd for Box { - #[inline] - fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(*other) } - } - impl TotalEq for Box {} } #[cfg(test)] diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 9cf3a76364887..af65fcc5a779d 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -10,8 +10,6 @@ //! The `Default` trait for types which may have meaningful default values -use owned::Box; - /// A trait that types which have a useful default value should implement. pub trait Default { /// Return the "default value" for a type. @@ -21,7 +19,3 @@ pub trait Default { impl Default for @T { fn default() -> @T { @Default::default() } } - -impl Default for Box { - fn default() -> Box { box Default::default() } -} diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 10ae30cf39d0c..f6a77d6decae0 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2334,7 +2334,7 @@ mod tests { use realstd::num; use cmp; - use owned::Box; + use realstd::owned::Box; use uint; #[test] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 06bd46fe9ad97..97b086a093d2a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -30,7 +30,6 @@ #[cfg(test)] pub use cmp = realcore::cmp; #[cfg(test)] pub use kinds = realcore::kinds; #[cfg(test)] pub use ops = realcore::ops; -#[cfg(test)] pub use owned = realcore::owned; #[cfg(test)] pub use ty = realcore::ty; #[cfg(not(test))] @@ -73,7 +72,6 @@ pub mod ptr; #[cfg(not(test))] pub mod ops; #[cfg(not(test))] pub mod ty; #[cfg(not(test))] pub mod cmp; -#[cfg(not(test))] pub mod owned; pub mod clone; pub mod default; pub mod container; @@ -95,6 +93,9 @@ pub mod slice; pub mod str; pub mod tuple; +#[cfg(stage0, not(test))] +pub mod owned; + mod failure; // FIXME: this module should not exist. Once owned allocations are no longer a diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index feb66f569645b..c5c6d75177728 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -380,7 +380,7 @@ mod tests { use mem::*; use option::{Some,None}; use realstd::str::StrAllocating; - use owned::Box; + use realstd::owned::Box; use raw; #[test] diff --git a/src/libcore/owned.rs b/src/libcore/owned.rs index d5cdd9c39b67c..3af12c5154c29 100644 --- a/src/libcore/owned.rs +++ b/src/libcore/owned.rs @@ -10,10 +10,14 @@ //! Operations on unique pointer types -// FIXME: this module should not exist in libcore. It must currently because the -// Box implementation is quite ad-hoc in the compiler. Once there is -// proper support in the compiler this type will be able to be defined in -// its own module. +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. @@ -23,16 +27,75 @@ /// let foo = box(HEAP) Bar::new(...); /// let foo = box Bar::new(...); #[lang="exchange_heap"] -#[cfg(not(test))] -pub static HEAP: () = (); - -#[cfg(test)] pub static HEAP: () = (); /// A type that represents a uniquely-owned value. #[lang="owned_box"] -#[cfg(not(test))] pub struct Box(*T); -#[cfg(test)] -pub struct Box(*T); +impl Default for Box { + fn default() -> Box { box Default::default() } +} + +impl Clone for Box { + /// Return a copy of the owned box. + #[inline] + fn clone(&self) -> Box { box {(**self).clone()} } + + /// Perform copy-assignment from `source` by reusing the existing allocation. + #[inline] + fn clone_from(&mut self, source: &Box) { + (**self).clone_from(&(**source)); + } +} + +// box pointers +impl Eq for Box { + #[inline] + fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } + #[inline] + fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } +} +impl Ord for Box { + #[inline] + fn lt(&self, other: &Box) -> bool { *(*self) < *(*other) } + #[inline] + fn le(&self, other: &Box) -> bool { *(*self) <= *(*other) } + #[inline] + fn ge(&self, other: &Box) -> bool { *(*self) >= *(*other) } + #[inline] + fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } +} +impl TotalOrd for Box { + #[inline] + fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(*other) } +} +impl TotalEq for Box {} + +/// 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(self) -> Result, Self>; +} + +impl AnyOwnExt for Box { + #[inline] + fn move(self) -> Result, Box> { + if self.is::() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = + *mem::transmute::<&Box, &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/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index f93eb4550a94a..f853b0dbad40f 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -90,7 +90,7 @@ fn get_base_type(inference_context: &InferCtxt, } } -fn type_is_defined_in_local_crate(original_type: t) -> bool { +fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool { /*! * * For coherence, when we have `impl Trait for Type`, we need to @@ -109,6 +109,14 @@ fn type_is_defined_in_local_crate(original_type: t) -> bool { found_nominal = true; } } + ty_uniq(..) => { + match tcx.lang_items.owned_box() { + Some(did) if did.krate == ast::LOCAL_CRATE => { + found_nominal = true; + } + _ => {} + } + } _ => { } } @@ -194,11 +202,10 @@ impl<'a> visit::Visitor<()> for PrivilegedScopeVisitor<'a> { } } ItemImpl(_, Some(ref trait_ref), _, _) => { + let tcx = self.cc.crate_context.tcx; // `for_ty` is `Type` in `impl Trait for Type` - let for_ty = - ty::node_id_to_type(self.cc.crate_context.tcx, - item.id); - if !type_is_defined_in_local_crate(for_ty) { + let for_ty = ty::node_id_to_type(tcx, item.id); + if !type_is_defined_in_local_crate(tcx, for_ty) { // This implementation is not in scope of its base // type. This still might be OK if the trait is // defined in the same crate. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 34ed7933c397f..a37f9a516fdb9 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 0000000000000..3af12c5154c29 --- /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 or the MIT license +// , 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); + +impl Default for Box { + fn default() -> Box { box Default::default() } +} + +impl Clone for Box { + /// Return a copy of the owned box. + #[inline] + fn clone(&self) -> Box { box {(**self).clone()} } + + /// Perform copy-assignment from `source` by reusing the existing allocation. + #[inline] + fn clone_from(&mut self, source: &Box) { + (**self).clone_from(&(**source)); + } +} + +// box pointers +impl Eq for Box { + #[inline] + fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } + #[inline] + fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } +} +impl Ord for Box { + #[inline] + fn lt(&self, other: &Box) -> bool { *(*self) < *(*other) } + #[inline] + fn le(&self, other: &Box) -> bool { *(*self) <= *(*other) } + #[inline] + fn ge(&self, other: &Box) -> bool { *(*self) >= *(*other) } + #[inline] + fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } +} +impl TotalOrd for Box { + #[inline] + fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(*other) } +} +impl TotalEq for Box {} + +/// 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(self) -> Result, Self>; +} + +impl AnyOwnExt for Box { + #[inline] + fn move(self) -> Result, Box> { + if self.is::() { + unsafe { + // Get the raw representation of the trait object + let to: TraitObject = + *mem::transmute::<&Box, &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 cd0445056b290..31a2014530607 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 2f7b31ae31d98..7fb61c29112de 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. /// diff --git a/src/test/run-pass/unit-like-struct-drop-run.rs b/src/test/run-pass/unit-like-struct-drop-run.rs index 29dbe35752aa1..ae4623c6e66eb 100644 --- a/src/test/run-pass/unit-like-struct-drop-run.rs +++ b/src/test/run-pass/unit-like-struct-drop-run.rs @@ -10,7 +10,7 @@ // Make sure the destructor is run for unit-like structs. -use std::any::AnyOwnExt; +use std::owned::AnyOwnExt; use std::task; struct Foo;