Skip to content

Commit cbc31df

Browse files
committed
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]
1 parent cb115ac commit cbc31df

File tree

14 files changed

+219
-105
lines changed

14 files changed

+219
-105
lines changed

src/libcore/any.rs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@
2222
2323
use mem::{transmute, transmute_copy};
2424
use option::{Option, Some, None};
25-
use owned::Box;
2625
use raw::TraitObject;
27-
use result::{Result, Ok, Err};
2826
use intrinsics::TypeId;
29-
use intrinsics;
3027

3128
/// A type with no inhabitants
3229
pub enum Void { }
@@ -117,38 +114,11 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any {
117114
}
118115
}
119116

120-
/// Extension methods for an owning `Any` trait object
121-
pub trait AnyOwnExt {
122-
/// Returns the boxed value if it is of type `T`, or
123-
/// `Err(Self)` if it isn't.
124-
fn move<T: 'static>(self) -> Result<Box<T>, Self>;
125-
}
126-
127-
impl AnyOwnExt for Box<Any> {
128-
#[inline]
129-
fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
130-
if self.is::<T>() {
131-
unsafe {
132-
// Get the raw representation of the trait object
133-
let to: TraitObject = transmute_copy(&self);
134-
135-
// Prevent destructor on self being run
136-
intrinsics::forget(self);
137-
138-
// Extract the data pointer
139-
Ok(transmute(to.data))
140-
}
141-
} else {
142-
Err(self)
143-
}
144-
}
145-
}
146-
147117
#[cfg(test)]
148118
mod tests {
149119
use prelude::*;
150120
use super::*;
151-
use owned::Box;
121+
use realstd::owned::{Box, AnyOwnExt};
152122
use realstd::str::StrAllocating;
153123

154124
#[deriving(Eq, Show)]
@@ -253,6 +223,8 @@ mod tests {
253223

254224
#[test]
255225
fn any_move() {
226+
use realstd::any::Any;
227+
use realstd::result::{Ok, Err};
256228
let a = box 8u as Box<Any>;
257229
let b = box Test as Box<Any>;
258230

src/libcore/clone.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ the `clone` method.
2121
2222
*/
2323

24-
use owned::Box;
25-
2624
/// A common trait for cloning an object.
2725
pub trait Clone {
2826
/// Returns a copy of the value. The contents of owned pointers
@@ -41,18 +39,6 @@ pub trait Clone {
4139
}
4240
}
4341

44-
impl<T: Clone> Clone for Box<T> {
45-
/// Return a copy of the owned box.
46-
#[inline]
47-
fn clone(&self) -> Box<T> { box {(**self).clone()} }
48-
49-
/// Perform copy-assignment from `source` by reusing the existing allocation.
50-
#[inline]
51-
fn clone_from(&mut self, source: &Box<T>) {
52-
(**self).clone_from(&(**source));
53-
}
54-
}
55-
5642
impl<T> Clone for @T {
5743
/// Return a shallow copy of the managed box.
5844
#[inline]
@@ -129,12 +115,22 @@ extern_fn_clone!(A, B, C, D, E, F, G, H)
129115
#[cfg(test)]
130116
mod test {
131117
use prelude::*;
132-
use owned::Box;
118+
use realstd::owned::Box;
119+
120+
fn realclone<T: ::realstd::clone::Clone>(t: &T) -> T {
121+
use realstd::clone::Clone;
122+
t.clone()
123+
}
124+
125+
fn realclone_from<T: ::realstd::clone::Clone>(t1: &mut T, t2: &T) {
126+
use realstd::clone::Clone;
127+
t1.clone_from(t2)
128+
}
133129

134130
#[test]
135131
fn test_owned_clone() {
136132
let a = box 5i;
137-
let b: Box<int> = a.clone();
133+
let b: Box<int> = realclone(&a);
138134
assert_eq!(a, b);
139135
}
140136

@@ -157,7 +153,7 @@ mod test {
157153
fn test_clone_from() {
158154
let a = box 5;
159155
let mut b = box 10;
160-
b.clone_from(&a);
156+
realclone_from(&mut b, &a);
161157
assert_eq!(*b, 5);
162158
}
163159

src/libcore/cmp.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ pub fn max<T: TotalOrd>(v1: T, v2: T) -> T {
193193
#[cfg(not(test))]
194194
mod impls {
195195
use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering};
196-
use owned::Box;
197196

198197
// & pointers
199198
impl<'a, T: Eq> Eq for &'a T {
@@ -240,29 +239,6 @@ mod impls {
240239
fn cmp(&self, other: &@T) -> Ordering { (**self).cmp(*other) }
241240
}
242241
impl<T: TotalEq> TotalEq for @T {}
243-
244-
// box pointers
245-
impl<T:Eq> Eq for Box<T> {
246-
#[inline]
247-
fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
248-
#[inline]
249-
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
250-
}
251-
impl<T:Ord> Ord for Box<T> {
252-
#[inline]
253-
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
254-
#[inline]
255-
fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
256-
#[inline]
257-
fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
258-
#[inline]
259-
fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
260-
}
261-
impl<T: TotalOrd> TotalOrd for Box<T> {
262-
#[inline]
263-
fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
264-
}
265-
impl<T: TotalEq> TotalEq for Box<T> {}
266242
}
267243

268244
#[cfg(test)]

src/libcore/default.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
//! The `Default` trait for types which may have meaningful default values
1212
13-
use owned::Box;
14-
1513
/// A trait that types which have a useful default value should implement.
1614
pub trait Default {
1715
/// Return the "default value" for a type.
@@ -21,7 +19,3 @@ pub trait Default {
2119
impl<T: Default + 'static> Default for @T {
2220
fn default() -> @T { @Default::default() }
2321
}
24-
25-
impl<T: Default> Default for Box<T> {
26-
fn default() -> Box<T> { box Default::default() }
27-
}

src/libcore/iter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2334,7 +2334,7 @@ mod tests {
23342334
use realstd::num;
23352335

23362336
use cmp;
2337-
use owned::Box;
2337+
use realstd::owned::Box;
23382338
use uint;
23392339

23402340
#[test]

src/libcore/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#[cfg(test)] pub use cmp = realcore::cmp;
3131
#[cfg(test)] pub use kinds = realcore::kinds;
3232
#[cfg(test)] pub use ops = realcore::ops;
33-
#[cfg(test)] pub use owned = realcore::owned;
3433
#[cfg(test)] pub use ty = realcore::ty;
3534

3635
#[cfg(not(test))]
@@ -73,7 +72,6 @@ pub mod ptr;
7372
#[cfg(not(test))] pub mod ops;
7473
#[cfg(not(test))] pub mod ty;
7574
#[cfg(not(test))] pub mod cmp;
76-
#[cfg(not(test))] pub mod owned;
7775
pub mod clone;
7876
pub mod default;
7977
pub mod container;
@@ -95,6 +93,9 @@ pub mod slice;
9593
pub mod str;
9694
pub mod tuple;
9795

96+
#[cfg(stage0, not(test))]
97+
pub mod owned;
98+
9899
mod failure;
99100

100101
// FIXME: this module should not exist. Once owned allocations are no longer a

src/libcore/mem.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ mod tests {
380380
use mem::*;
381381
use option::{Some,None};
382382
use realstd::str::StrAllocating;
383-
use owned::Box;
383+
use realstd::owned::Box;
384384
use raw;
385385

386386
#[test]

src/libcore/owned.rs

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010

1111
//! Operations on unique pointer types
1212
13-
// FIXME: this module should not exist in libcore. It must currently because the
14-
// Box implementation is quite ad-hoc in the compiler. Once there is
15-
// proper support in the compiler this type will be able to be defined in
16-
// its own module.
13+
use any::{Any, AnyRefExt};
14+
use clone::Clone;
15+
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering};
16+
use default::Default;
17+
use intrinsics;
18+
use mem;
19+
use raw::TraitObject;
20+
use result::{Ok, Err, Result};
1721

1822
/// A value that represents the global exchange heap. This is the default
1923
/// place that the `box` keyword allocates into when no place is supplied.
@@ -23,16 +27,75 @@
2327
/// let foo = box(HEAP) Bar::new(...);
2428
/// let foo = box Bar::new(...);
2529
#[lang="exchange_heap"]
26-
#[cfg(not(test))]
27-
pub static HEAP: () = ();
28-
29-
#[cfg(test)]
3030
pub static HEAP: () = ();
3131

3232
/// A type that represents a uniquely-owned value.
3333
#[lang="owned_box"]
34-
#[cfg(not(test))]
3534
pub struct Box<T>(*T);
3635

37-
#[cfg(test)]
38-
pub struct Box<T>(*T);
36+
impl<T: Default> Default for Box<T> {
37+
fn default() -> Box<T> { box Default::default() }
38+
}
39+
40+
impl<T: Clone> Clone for Box<T> {
41+
/// Return a copy of the owned box.
42+
#[inline]
43+
fn clone(&self) -> Box<T> { box {(**self).clone()} }
44+
45+
/// Perform copy-assignment from `source` by reusing the existing allocation.
46+
#[inline]
47+
fn clone_from(&mut self, source: &Box<T>) {
48+
(**self).clone_from(&(**source));
49+
}
50+
}
51+
52+
// box pointers
53+
impl<T:Eq> Eq for Box<T> {
54+
#[inline]
55+
fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
56+
#[inline]
57+
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
58+
}
59+
impl<T:Ord> Ord for Box<T> {
60+
#[inline]
61+
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
62+
#[inline]
63+
fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
64+
#[inline]
65+
fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
66+
#[inline]
67+
fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
68+
}
69+
impl<T: TotalOrd> TotalOrd for Box<T> {
70+
#[inline]
71+
fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
72+
}
73+
impl<T: TotalEq> TotalEq for Box<T> {}
74+
75+
/// Extension methods for an owning `Any` trait object
76+
pub trait AnyOwnExt {
77+
/// Returns the boxed value if it is of type `T`, or
78+
/// `Err(Self)` if it isn't.
79+
fn move<T: 'static>(self) -> Result<Box<T>, Self>;
80+
}
81+
82+
impl AnyOwnExt for Box<Any> {
83+
#[inline]
84+
fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
85+
if self.is::<T>() {
86+
unsafe {
87+
// Get the raw representation of the trait object
88+
let to: TraitObject =
89+
*mem::transmute::<&Box<Any>, &TraitObject>(&self);
90+
91+
// Prevent destructor on self being run
92+
intrinsics::forget(self);
93+
94+
// Extract the data pointer
95+
Ok(mem::transmute(to.data))
96+
}
97+
} else {
98+
Err(self)
99+
}
100+
}
101+
}

src/librustc/middle/typeck/coherence.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn get_base_type(inference_context: &InferCtxt,
9090
}
9191
}
9292

93-
fn type_is_defined_in_local_crate(original_type: t) -> bool {
93+
fn type_is_defined_in_local_crate(tcx: &ty::ctxt, original_type: t) -> bool {
9494
/*!
9595
*
9696
* 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 {
109109
found_nominal = true;
110110
}
111111
}
112+
ty_uniq(..) => {
113+
match tcx.lang_items.owned_box() {
114+
Some(did) if did.krate == ast::LOCAL_CRATE => {
115+
found_nominal = true;
116+
}
117+
_ => {}
118+
}
119+
}
112120

113121
_ => { }
114122
}
@@ -194,11 +202,10 @@ impl<'a> visit::Visitor<()> for PrivilegedScopeVisitor<'a> {
194202
}
195203
}
196204
ItemImpl(_, Some(ref trait_ref), _, _) => {
205+
let tcx = self.cc.crate_context.tcx;
197206
// `for_ty` is `Type` in `impl Trait for Type`
198-
let for_ty =
199-
ty::node_id_to_type(self.cc.crate_context.tcx,
200-
item.id);
201-
if !type_is_defined_in_local_crate(for_ty) {
207+
let for_ty = ty::node_id_to_type(tcx, item.id);
208+
if !type_is_defined_in_local_crate(tcx, for_ty) {
202209
// This implementation is not in scope of its base
203210
// type. This still might be OK if the trait is
204211
// defined in the same crate.

src/libstd/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,16 @@ extern crate core;
133133
#[cfg(test)] pub use ops = realstd::ops;
134134
#[cfg(test)] pub use cmp = realstd::cmp;
135135
#[cfg(test)] pub use ty = realstd::ty;
136-
#[cfg(test)] pub use owned = realstd::owned;
136+
#[cfg(not(stage0), test)] pub use owned = realstd::owned;
137137

138138
#[cfg(not(test))] pub use cmp = core::cmp;
139139
#[cfg(not(test))] pub use kinds = core::kinds;
140140
#[cfg(not(test))] pub use ops = core::ops;
141-
#[cfg(not(test))] pub use owned = core::owned;
142141
#[cfg(not(test))] pub use ty = core::ty;
143142

143+
#[cfg(stage0, test)] pub use owned = realstd::owned;
144+
#[cfg(stage0, not(test))] pub use owned = core::owned;
145+
144146
pub use core::any;
145147
pub use core::bool;
146148
pub use core::cell;
@@ -207,6 +209,8 @@ pub mod ascii;
207209

208210
pub mod rc;
209211
pub mod gc;
212+
#[cfg(not(stage0), not(test))]
213+
pub mod owned;
210214

211215
/* Common traits */
212216

0 commit comments

Comments
 (0)