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

[WIP] Start adding support for opt-in built-in traits #14371

Closed
wants to merge 13 commits into from
6 changes: 6 additions & 0 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub struct Arc<T> {
_ptr: *mut ArcInner<T>,
}

impl<T: Share> Share for Arc<T> {}

/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
Expand All @@ -68,12 +70,16 @@ pub struct Weak<T> {
_ptr: *mut ArcInner<T>,
}

impl<T: Share> Share for Weak<T> {}

struct ArcInner<T> {
strong: atomics::AtomicUint,
weak: atomics::AtomicUint,
data: T,
}

impl<T: Share> Share for ArcInner<T> {}

impl<T: Share + Send> Arc<T> {
/// Create an atomically reference counted wrapper.
#[inline]
Expand Down
1 change: 1 addition & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ mod std {
pub use core::fmt; // necessary for fail!()
pub use core::option; // necessary for fail!()
pub use core::clone; // deriving(Clone)
pub use core::kinds; // deriving(Share,Send,Copy)
pub use core::cmp; // deriving(Eq, Ord, etc.)
pub use hash; // deriving(Hash)
}
3 changes: 2 additions & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
Expand Down Expand Up @@ -25,7 +26,7 @@ use str::{CharRange, StrAllocating};
use vec::Vec;

/// A growable string stored as a UTF-8 encoded buffer.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Share)]
pub struct String {
vec: Vec<u8>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcollections/treemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use vec::Vec;
// These would be convenient since the methods work like `each`

#[allow(missing_doc)]
#[deriving(Clone)]
#[deriving(Clone, Share)]
pub struct TreeMap<K, V> {
root: Option<Box<TreeNode<K, V>>>,
length: uint
Expand Down
3 changes: 3 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub struct Vec<T> {
ptr: *mut T
}

impl <T: Send> Send for Vec<T> {}
impl <T: Share> Share for Vec<T> {}

impl<T> Vec<T> {
/// Constructs a new, empty `Vec`.
///
Expand Down
4 changes: 4 additions & 0 deletions src/libcore/atomics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,28 @@ use std::kinds::marker;
use ty::Unsafe;

/// An atomic boolean type.
#[deriving(Share)]
pub struct AtomicBool {
v: Unsafe<uint>,
nocopy: marker::NoCopy
}

/// A signed atomic integer type, supporting basic atomic arithmetic operations
#[deriving(Share)]
pub struct AtomicInt {
v: Unsafe<int>,
nocopy: marker::NoCopy
}

/// An unsigned atomic integer type, supporting basic atomic arithmetic operations
#[deriving(Share)]
pub struct AtomicUint {
v: Unsafe<uint>,
nocopy: marker::NoCopy
}

/// An unsafe atomic pointer. Only supports basic atomic operations
#[deriving(Share)]
pub struct AtomicPtr<T> {
p: Unsafe<uint>,
nocopy: marker::NoCopy
Expand Down
16 changes: 16 additions & 0 deletions src/libcore/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#![doc(primitive = "bool")]

#[cfg(not(stage0))]
use kinds::{Send, Share, Copy};

use num::{Int, one, zero};

/////////////////////////////////////////////////////////////////////////////
Expand All @@ -35,6 +38,19 @@ pub fn to_bit<N: Int>(p: bool) -> N {
if p { one() } else { zero() }
}

/////////////////////////////////////////////////////////////////////////////
// Trait impls on `bool`
/////////////////////////////////////////////////////////////////////////////

#[cfg(not(stage0))]
impl Send for bool { }

#[cfg(not(stage0))]
impl Share for bool { }

#[cfg(not(stage0))]
impl Copy for bool { }

#[cfg(test)]
mod tests {
use realstd::prelude::*;
Expand Down
19 changes: 19 additions & 0 deletions src/libcore/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ pub trait Send {
// empty.
}

#[cfg(not(stage0))]
impl<T:Send> Send for *T { }

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
Expand All @@ -38,6 +41,13 @@ pub trait Copy {
// Empty.
}

#[cfg(not(stage0))]
impl<T> Copy for *T { }

#[cfg(not(stage0))]
impl<'a, T> Copy for &'a T { }


/// Types that can be safely shared between tasks when aliased.
///
/// The precise definition is: a type `T` is `Share` if `&T` is
Expand Down Expand Up @@ -88,6 +98,15 @@ pub trait Share {
// Empty
}

#[cfg(not(stage0))]
impl<T:Share> Share for *T { }

#[cfg(not(stage0))]
impl<'a,T:Share> Share for &'a T { }

#[cfg(not(stage0))]
impl<'a,T:Share> Share for &'a mut T { }

/// Marker types are special types that are used with unsafe code to
/// inform the compiler of special constraints. Marker types should
/// only be needed when you are creating an abstraction that is
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/num/i16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "i16")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

int_module!(i16, 16)

3 changes: 3 additions & 0 deletions src/libcore/num/i32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "i32")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

int_module!(i32, 32)

3 changes: 3 additions & 0 deletions src/libcore/num/i64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "i64")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

int_module!(i64, 64)

3 changes: 3 additions & 0 deletions src/libcore/num/i8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "i8")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

int_module!(i8, 8)

3 changes: 3 additions & 0 deletions src/libcore/num/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

#![doc(primitive = "int")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

#[cfg(target_word_size = "32")] int_module!(int, 32)
#[cfg(target_word_size = "64")] int_module!(int, 64)

9 changes: 9 additions & 0 deletions src/libcore/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ pub static MIN: $T = (-1 as $T) << (BITS - 1);
// calling the `Bounded::max_value` function.
pub static MAX: $T = !MIN;

#[cfg(not(stage0))]
impl Send for $T { }

#[cfg(not(stage0))]
impl Share for $T { }

#[cfg(not(stage0))]
impl Copy for $T { }

#[cfg(test)]
mod tests {
use prelude::*;
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/num/u16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@

#![doc(primitive = "u16")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

uint_module!(u16, i16, 16)
3 changes: 3 additions & 0 deletions src/libcore/num/u32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "u32")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

uint_module!(u32, i32, 32)

3 changes: 3 additions & 0 deletions src/libcore/num/u64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "u64")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

uint_module!(u64, i64, 64)

3 changes: 3 additions & 0 deletions src/libcore/num/u8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "u8")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

uint_module!(u8, i8, 8)

3 changes: 3 additions & 0 deletions src/libcore/num/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@

#![doc(primitive = "uint")]

#[cfg(not(stage0))]
use kinds::{Share, Send, Copy};

uint_module!(uint, int, ::int::BITS)

9 changes: 9 additions & 0 deletions src/libcore/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ pub static BYTES : uint = ($bits / 8);
pub static MIN: $T = 0 as $T;
pub static MAX: $T = 0 as $T - 1 as $T;

#[cfg(not(stage0))]
impl Send for $T { }

#[cfg(not(stage0))]
impl Share for $T { }

#[cfg(not(stage0))]
impl Copy for $T { }

#[cfg(test)]
mod tests {
use prelude::*;
Expand Down
5 changes: 5 additions & 0 deletions src/libcore/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
use clone::Clone;
#[cfg(not(test))] use cmp::*;
#[cfg(not(test))] use default::Default;
use kinds::{Copy, Send, Share};

// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
Expand All @@ -82,6 +83,10 @@ macro_rules! tuple_impls {
$(fn $mutN<'a>(&'a mut self) -> &'a mut $T;)+
}

impl<$($T:Copy),+> Copy for ($($T,)+) {}
impl<$($T:Send),+> Send for ($($T,)+) {}
impl<$($T:Share),+> Share for ($($T,)+) {}

impl<$($T),+> $Tuple<$($T),+> for ($($T,)+) {
$(
#[inline]
Expand Down
4 changes: 3 additions & 1 deletion src/libcore/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

//! Types dealing with unsafe actions.

use kinds::marker;
use kinds::{Share,marker};

/// Unsafe type that wraps a type T and indicates unsafe interior operations on the
/// wrapped type. Types with an `Unsafe<T>` field are considered to have an *unsafe
Expand Down Expand Up @@ -53,6 +53,8 @@ pub struct Unsafe<T> {
pub marker1: marker::InvariantType<T>
}

impl <T> Share for Unsafe<T> {}

impl<T> Unsafe<T> {

/// Static constructor
Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/file_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use io::util;

pub type fd_t = libc::c_int;

#[deriving(Share)]
struct Inner {
fd: fd_t,
close_on_drop: bool,
Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ pub struct TcpStream {
write_deadline: u64,
}

#[deriving(Share)]
struct Inner {
fd: sock_t,

Expand Down
1 change: 1 addition & 0 deletions src/libnative/io/pipe_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ fn addr_to_sockaddr_un(addr: &CString) -> IoResult<(libc::sockaddr_storage, uint
return Ok((storage, len));
}

#[deriving(Share)]
struct Inner {
fd: fd_t,

Expand Down
17 changes: 16 additions & 1 deletion src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,25 @@ pub fn check_builtin_bounds(cx: &Context,
let kind = ty::type_contents(cx.tcx, ty);
let mut missing = ty::empty_builtin_bounds();
for bound in bounds.iter() {
if !kind.meets_bound(cx.tcx, bound) {
// FIXME(flaper87): This is temporary. The reason
// this code is here is because we'll move one trait
// at a time. Remaining traits will still rely on
// TypeContents.
let meets_bound = match bound {
ty::BoundStatic => kind.is_static(cx.tcx),
ty::BoundSend => kind.is_sendable(cx.tcx),
ty::BoundSized => kind.is_sized(cx.tcx),
ty::BoundCopy => kind.is_copy(cx.tcx),
ty::BoundShare => {
ty::type_fulfills_share(cx.tcx, ty)
}
};

if !meets_bound {
missing.add(bound);
}
}

if !missing.is_empty() {
any_missing(missing);
}
Expand Down
Loading