Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Move the owned module from core to std #14184

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 3 additions & 31 deletions src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 { }
Expand Down Expand Up @@ -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<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 = 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)]
Expand Down Expand Up @@ -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<Any>;
let b = box Test as Box<Any>;

Expand Down
30 changes: 13 additions & 17 deletions src/libcore/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -41,18 +39,6 @@ pub trait Clone {
}
}

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));
}
}

impl<T> Clone for @T {
/// Return a shallow copy of the managed box.
#[inline]
Expand Down Expand Up @@ -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: ::realstd::clone::Clone>(t: &T) -> T {
use realstd::clone::Clone;
t.clone()
}

fn realclone_from<T: ::realstd::clone::Clone>(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<int> = a.clone();
let b: Box<int> = realclone(&a);
assert_eq!(a, b);
}

Expand All @@ -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);
}

Expand Down
24 changes: 0 additions & 24 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ pub fn max<T: TotalOrd>(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 {
Expand Down Expand Up @@ -240,29 +239,6 @@ mod impls {
fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
}
impl<T: TotalEq> TotalEq for @T {}

// 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> {}
}

#[cfg(test)]
Expand Down
6 changes: 0 additions & 6 deletions src/libcore/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -21,7 +19,3 @@ pub trait Default {
impl<T: Default + 'static> Default for @T {
fn default() -> @T { @Default::default() }
}

impl<T: Default> Default for Box<T> {
fn default() -> Box<T> { box Default::default() }
}
2 changes: 1 addition & 1 deletion src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2334,7 +2334,7 @@ mod tests {
use realstd::num;

use cmp;
use owned::Box;
use realstd::owned::Box;
use uint;

#[test]
Expand Down
5 changes: 3 additions & 2 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
85 changes: 74 additions & 11 deletions src/libcore/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@

//! Operations on unique pointer types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this should've been deleted? (it's libcore/owned.rs)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully soon! This is needed for bootstrapping, however (it's cfg(stage0) in libcore/lib.rs)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, whoops; I was actually assuming that there would be staging required, but then completely missed it. :/


// 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.
Expand All @@ -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>(*T);

#[cfg(test)]
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)
}
}
}
17 changes: 12 additions & 5 deletions src/librustc/middle/typeck/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
_ => {}
}
}

_ => { }
}
Expand Down Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -207,6 +209,8 @@ pub mod ascii;

pub mod rc;
pub mod gc;
#[cfg(not(stage0), not(test))]
pub mod owned;

/* Common traits */

Expand Down
Loading