Add a Share kind

Fixes #11781
This commit is contained in:
Flavio Percoco 2014-03-03 23:27:46 +01:00
parent a92dcb0828
commit 37154fb8b9
7 changed files with 76 additions and 29 deletions

View File

@ -603,6 +603,9 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
'P' => {
param_bounds.builtin_bounds.add(ty::BoundPod);
}
'T' => {
param_bounds.builtin_bounds.add(ty::BoundShare);
}
'I' => {
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
}

View File

@ -410,6 +410,7 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
ty::BoundStatic => mywrite!(w, "O"),
ty::BoundSized => mywrite!(w, "Z"),
ty::BoundPod => mywrite!(w, "P"),
ty::BoundShare => mywrite!(w, "T"),
}
}

View File

@ -22,7 +22,7 @@
use driver::session::Session;
use metadata::csearch::each_lang_item;
use middle::ty::{BuiltinBound, BoundFreeze, BoundPod, BoundSend, BoundSized};
use middle::ty;
use syntax::ast;
use syntax::ast_util::local_def;
use syntax::attr::AttrMetaMethods;
@ -82,15 +82,17 @@ impl LanguageItems {
}
}
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<BuiltinBound> {
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
if Some(id) == self.freeze_trait() {
Some(BoundFreeze)
Some(ty::BoundFreeze)
} else if Some(id) == self.send_trait() {
Some(BoundSend)
Some(ty::BoundSend)
} else if Some(id) == self.sized_trait() {
Some(BoundSized)
Some(ty::BoundSized)
} else if Some(id) == self.pod_trait() {
Some(BoundPod)
Some(ty::BoundPod)
} else if Some(id) == self.share_trait() {
Some(ty::BoundShare)
} else {
None
}
@ -213,6 +215,7 @@ lets_do_this! {
SendTraitLangItem, "send", send_trait;
SizedTraitLangItem, "sized", sized_trait;
PodTraitLangItem, "pod", pod_trait;
ShareTraitLangItem, "share", share_trait;
DropTraitLangItem, "drop", drop_trait;
@ -274,5 +277,6 @@ lets_do_this! {
NoFreezeItem, "no_freeze_bound", no_freeze_bound;
NoSendItem, "no_send_bound", no_send_bound;
NoPodItem, "no_pod_bound", no_pod_bound;
NoShareItem, "no_share_bound", no_share_bound;
ManagedItem, "managed_bound", managed_bound;
}

View File

@ -850,6 +850,7 @@ pub enum BuiltinBound {
BoundFreeze,
BoundSized,
BoundPod,
BoundShare,
}
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
@ -862,6 +863,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
set.add(BoundSend);
set.add(BoundFreeze);
set.add(BoundSized);
set.add(BoundShare);
set
}
@ -1872,31 +1874,32 @@ macro_rules! def_type_content_sets(
def_type_content_sets!(
mod TC {
None = 0b0000__00000000__0000,
None = 0b0000_0000__0000_0000__0000,
// Things that are interior to the value (first nibble):
InteriorUnsized = 0b0000__00000000__0001,
// InteriorAll = 0b0000__00000000__1111,
InteriorUnsized = 0b0000_0000__0000_0000__0001,
// InteriorAll = 0b0000_0000__0000_0000__1111,
// Things that are owned by the value (second and third nibbles):
OwnsOwned = 0b0000__00000001__0000,
OwnsDtor = 0b0000__00000010__0000,
OwnsManaged /* see [1] below */ = 0b0000__00000100__0000,
OwnsAffine = 0b0000__00001000__0000,
OwnsAll = 0b0000__11111111__0000,
OwnsOwned = 0b0000_0000__0000_0001__0000,
OwnsDtor = 0b0000_0000__0000_0010__0000,
OwnsManaged /* see [1] below */ = 0b0000_0000__0000_0100__0000,
OwnsAffine = 0b0000_0000__0000_1000__0000,
OwnsAll = 0b0000_0000__1111_1111__0000,
// Things that are reachable by the value in any way (fourth nibble):
ReachesNonsendAnnot = 0b0001__00000000__0000,
ReachesBorrowed = 0b0010__00000000__0000,
// ReachesManaged /* see [1] below */ = 0b0100__00000000__0000,
ReachesMutable = 0b1000__00000000__0000,
ReachesAll = 0b1111__00000000__0000,
ReachesNonsendAnnot = 0b0000_0001__0000_0000__0000,
ReachesBorrowed = 0b0000_0010__0000_0000__0000,
// ReachesManaged /* see [1] below */ = 0b0000_0100__0000_0000__0000,
ReachesMutable = 0b0000_1000__0000_0000__0000,
ReachesNoShare = 0b0001_0000__0000_0000__0000,
ReachesAll = 0b0001_1111__0000_0000__0000,
// Things that cause values to *move* rather than *copy*
Moves = 0b0000__00001011__0000,
Moves = 0b0000_0000__0000_1011__0000,
// Things that mean drop glue is necessary
NeedsDrop = 0b0000__00000111__0000,
NeedsDrop = 0b0000_0000__0000_0111__0000,
// Things that prevent values from being sent
//
@ -1905,31 +1908,34 @@ def_type_content_sets!(
// both ReachesManaged and OwnsManaged so that when
// a parameter has a bound T:Send, we are able to deduce
// that it neither reaches nor owns a managed pointer.
Nonsendable = 0b0111__00000100__0000,
Nonsendable = 0b0000_0111__0000_0100__0000,
// Things that prevent values from being considered freezable
Nonfreezable = 0b1000__00000000__0000,
Nonfreezable = 0b0000_1000__0000_0000__0000,
// Things that prevent values from being considered 'static
Nonstatic = 0b0010__00000000__0000,
Nonstatic = 0b0000_0010__0000_0000__0000,
// Things that prevent values from being considered sized
Nonsized = 0b0000__00000000__0001,
Nonsized = 0b0000_0000__0000_0000__0001,
// Things that prevent values from being shared
Nonsharable = 0b0001_0000__0000_0000__0000,
// Things that make values considered not POD (would be same
// as `Moves`, but for the fact that managed data `@` is
// not considered POD)
Nonpod = 0b0000__00001111__0000,
Nonpod = 0b0000_0000__0000_1111__0000,
// Bits to set when a managed value is encountered
//
// [1] Do not set the bits TC::OwnsManaged or
// TC::ReachesManaged directly, instead reference
// TC::Managed to set them both at once.
Managed = 0b0100__00000100__0000,
Managed = 0b0000_0100__0000_0100__0000,
// All bits
All = 0b1111__11111111__1111
All = 0b1111_1111__1111_1111__1111
}
)
@ -1945,6 +1951,7 @@ impl TypeContents {
BoundSend => self.is_sendable(cx),
BoundSized => self.is_sized(cx),
BoundPod => self.is_pod(cx),
BoundShare => self.is_sharable(cx),
}
}
@ -1964,6 +1971,10 @@ impl TypeContents {
!self.intersects(TC::Nonsendable)
}
pub fn is_sharable(&self, _: &ctxt) -> bool {
!self.intersects(TC::Nonsharable)
}
pub fn owns_managed(&self) -> bool {
self.intersects(TC::OwnsManaged)
}
@ -2284,6 +2295,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
tc | TC::Managed
} else if Some(did) == cx.lang_items.no_pod_bound() {
tc | TC::OwnsAffine
} else if Some(did) == cx.lang_items.no_share_bound() {
tc | TC::ReachesNoShare
} else {
tc
}
@ -2362,6 +2375,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
BoundFreeze => TC::Nonfreezable,
BoundSized => TC::Nonsized,
BoundPod => TC::Nonpod,
BoundShare => TC::Nonsharable,
};
});
return tc;

View File

@ -674,6 +674,7 @@ impl Repr for ty::ParamBounds {
ty::BoundFreeze => ~"Freeze",
ty::BoundSized => ~"Sized",
ty::BoundPod => ~"Pod",
ty::BoundShare => ~"Share",
});
}
for t in self.trait_bounds.iter() {
@ -961,6 +962,7 @@ impl UserString for ty::BuiltinBound {
ty::BoundFreeze => ~"Freeze",
ty::BoundSized => ~"Sized",
ty::BoundPod => ~"Pod",
ty::BoundShare => ~"Share",
}
}
}

View File

@ -46,6 +46,22 @@ pub trait Pod {
// Empty.
}
/// Types that can be safely shared between threads, hence thread-safe.
#[cfg(stage0)]
pub trait Share {
// Empty
}
#[cfg(stage0)]
impl<T> Share for T {}
/// Types that can be safely shared between threads, hence thread-safe.
#[cfg(not(stage0))]
#[lang="share"]
pub trait Share {
// Empty
}
/// 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
@ -232,6 +248,13 @@ pub mod marker {
#[deriving(Eq,Clone)]
pub struct NoPod;
/// A type which is considered "not sharable", meaning that
/// its contents are not threadsafe, hence they cannot be
/// shared between tasks.
#[lang="no_share_bound"]
#[deriving(Eq,Clone)]
pub struct NoShare;
/// A type which is considered managed by the GC. This is typically
/// embedded in other types.
#[lang="managed_bound"]

View File

@ -20,7 +20,7 @@ generally useful to many Rust programs.
*/
// Reexported core operators
pub use kinds::{Freeze, Pod, Send, Sized};
pub use kinds::{Freeze, Pod, Send, Sized, Share};
pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop, Deref, DerefMut};