Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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