parent
a92dcb0828
commit
37154fb8b9
7 changed files with 76 additions and 29 deletions
|
@ -603,6 +603,9 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
|
||||||
'P' => {
|
'P' => {
|
||||||
param_bounds.builtin_bounds.add(ty::BoundPod);
|
param_bounds.builtin_bounds.add(ty::BoundPod);
|
||||||
}
|
}
|
||||||
|
'T' => {
|
||||||
|
param_bounds.builtin_bounds.add(ty::BoundShare);
|
||||||
|
}
|
||||||
'I' => {
|
'I' => {
|
||||||
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
|
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,6 +410,7 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
|
||||||
ty::BoundStatic => mywrite!(w, "O"),
|
ty::BoundStatic => mywrite!(w, "O"),
|
||||||
ty::BoundSized => mywrite!(w, "Z"),
|
ty::BoundSized => mywrite!(w, "Z"),
|
||||||
ty::BoundPod => mywrite!(w, "P"),
|
ty::BoundPod => mywrite!(w, "P"),
|
||||||
|
ty::BoundShare => mywrite!(w, "T"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use metadata::csearch::each_lang_item;
|
use metadata::csearch::each_lang_item;
|
||||||
use middle::ty::{BuiltinBound, BoundFreeze, BoundPod, BoundSend, BoundSized};
|
use middle::ty;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_util::local_def;
|
use syntax::ast_util::local_def;
|
||||||
use syntax::attr::AttrMetaMethods;
|
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() {
|
if Some(id) == self.freeze_trait() {
|
||||||
Some(BoundFreeze)
|
Some(ty::BoundFreeze)
|
||||||
} else if Some(id) == self.send_trait() {
|
} else if Some(id) == self.send_trait() {
|
||||||
Some(BoundSend)
|
Some(ty::BoundSend)
|
||||||
} else if Some(id) == self.sized_trait() {
|
} else if Some(id) == self.sized_trait() {
|
||||||
Some(BoundSized)
|
Some(ty::BoundSized)
|
||||||
} else if Some(id) == self.pod_trait() {
|
} else if Some(id) == self.pod_trait() {
|
||||||
Some(BoundPod)
|
Some(ty::BoundPod)
|
||||||
|
} else if Some(id) == self.share_trait() {
|
||||||
|
Some(ty::BoundShare)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -213,6 +215,7 @@ lets_do_this! {
|
||||||
SendTraitLangItem, "send", send_trait;
|
SendTraitLangItem, "send", send_trait;
|
||||||
SizedTraitLangItem, "sized", sized_trait;
|
SizedTraitLangItem, "sized", sized_trait;
|
||||||
PodTraitLangItem, "pod", pod_trait;
|
PodTraitLangItem, "pod", pod_trait;
|
||||||
|
ShareTraitLangItem, "share", share_trait;
|
||||||
|
|
||||||
DropTraitLangItem, "drop", drop_trait;
|
DropTraitLangItem, "drop", drop_trait;
|
||||||
|
|
||||||
|
@ -274,5 +277,6 @@ lets_do_this! {
|
||||||
NoFreezeItem, "no_freeze_bound", no_freeze_bound;
|
NoFreezeItem, "no_freeze_bound", no_freeze_bound;
|
||||||
NoSendItem, "no_send_bound", no_send_bound;
|
NoSendItem, "no_send_bound", no_send_bound;
|
||||||
NoPodItem, "no_pod_bound", no_pod_bound;
|
NoPodItem, "no_pod_bound", no_pod_bound;
|
||||||
|
NoShareItem, "no_share_bound", no_share_bound;
|
||||||
ManagedItem, "managed_bound", managed_bound;
|
ManagedItem, "managed_bound", managed_bound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -850,6 +850,7 @@ pub enum BuiltinBound {
|
||||||
BoundFreeze,
|
BoundFreeze,
|
||||||
BoundSized,
|
BoundSized,
|
||||||
BoundPod,
|
BoundPod,
|
||||||
|
BoundShare,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
|
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
|
||||||
|
@ -862,6 +863,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
|
||||||
set.add(BoundSend);
|
set.add(BoundSend);
|
||||||
set.add(BoundFreeze);
|
set.add(BoundFreeze);
|
||||||
set.add(BoundSized);
|
set.add(BoundSized);
|
||||||
|
set.add(BoundShare);
|
||||||
set
|
set
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1872,31 +1874,32 @@ macro_rules! def_type_content_sets(
|
||||||
|
|
||||||
def_type_content_sets!(
|
def_type_content_sets!(
|
||||||
mod TC {
|
mod TC {
|
||||||
None = 0b0000__00000000__0000,
|
None = 0b0000_0000__0000_0000__0000,
|
||||||
|
|
||||||
// Things that are interior to the value (first nibble):
|
// Things that are interior to the value (first nibble):
|
||||||
InteriorUnsized = 0b0000__00000000__0001,
|
InteriorUnsized = 0b0000_0000__0000_0000__0001,
|
||||||
// InteriorAll = 0b0000__00000000__1111,
|
// InteriorAll = 0b0000_0000__0000_0000__1111,
|
||||||
|
|
||||||
// Things that are owned by the value (second and third nibbles):
|
// Things that are owned by the value (second and third nibbles):
|
||||||
OwnsOwned = 0b0000__00000001__0000,
|
OwnsOwned = 0b0000_0000__0000_0001__0000,
|
||||||
OwnsDtor = 0b0000__00000010__0000,
|
OwnsDtor = 0b0000_0000__0000_0010__0000,
|
||||||
OwnsManaged /* see [1] below */ = 0b0000__00000100__0000,
|
OwnsManaged /* see [1] below */ = 0b0000_0000__0000_0100__0000,
|
||||||
OwnsAffine = 0b0000__00001000__0000,
|
OwnsAffine = 0b0000_0000__0000_1000__0000,
|
||||||
OwnsAll = 0b0000__11111111__0000,
|
OwnsAll = 0b0000_0000__1111_1111__0000,
|
||||||
|
|
||||||
// Things that are reachable by the value in any way (fourth nibble):
|
// Things that are reachable by the value in any way (fourth nibble):
|
||||||
ReachesNonsendAnnot = 0b0001__00000000__0000,
|
ReachesNonsendAnnot = 0b0000_0001__0000_0000__0000,
|
||||||
ReachesBorrowed = 0b0010__00000000__0000,
|
ReachesBorrowed = 0b0000_0010__0000_0000__0000,
|
||||||
// ReachesManaged /* see [1] below */ = 0b0100__00000000__0000,
|
// ReachesManaged /* see [1] below */ = 0b0000_0100__0000_0000__0000,
|
||||||
ReachesMutable = 0b1000__00000000__0000,
|
ReachesMutable = 0b0000_1000__0000_0000__0000,
|
||||||
ReachesAll = 0b1111__00000000__0000,
|
ReachesNoShare = 0b0001_0000__0000_0000__0000,
|
||||||
|
ReachesAll = 0b0001_1111__0000_0000__0000,
|
||||||
|
|
||||||
// Things that cause values to *move* rather than *copy*
|
// 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
|
// Things that mean drop glue is necessary
|
||||||
NeedsDrop = 0b0000__00000111__0000,
|
NeedsDrop = 0b0000_0000__0000_0111__0000,
|
||||||
|
|
||||||
// Things that prevent values from being sent
|
// Things that prevent values from being sent
|
||||||
//
|
//
|
||||||
|
@ -1905,31 +1908,34 @@ def_type_content_sets!(
|
||||||
// both ReachesManaged and OwnsManaged so that when
|
// both ReachesManaged and OwnsManaged so that when
|
||||||
// a parameter has a bound T:Send, we are able to deduce
|
// a parameter has a bound T:Send, we are able to deduce
|
||||||
// that it neither reaches nor owns a managed pointer.
|
// 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
|
// 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
|
// 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
|
// 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
|
// Things that make values considered not POD (would be same
|
||||||
// as `Moves`, but for the fact that managed data `@` is
|
// as `Moves`, but for the fact that managed data `@` is
|
||||||
// not considered POD)
|
// not considered POD)
|
||||||
Nonpod = 0b0000__00001111__0000,
|
Nonpod = 0b0000_0000__0000_1111__0000,
|
||||||
|
|
||||||
// Bits to set when a managed value is encountered
|
// Bits to set when a managed value is encountered
|
||||||
//
|
//
|
||||||
// [1] Do not set the bits TC::OwnsManaged or
|
// [1] Do not set the bits TC::OwnsManaged or
|
||||||
// TC::ReachesManaged directly, instead reference
|
// TC::ReachesManaged directly, instead reference
|
||||||
// TC::Managed to set them both at once.
|
// TC::Managed to set them both at once.
|
||||||
Managed = 0b0100__00000100__0000,
|
Managed = 0b0000_0100__0000_0100__0000,
|
||||||
|
|
||||||
// All bits
|
// All bits
|
||||||
All = 0b1111__11111111__1111
|
All = 0b1111_1111__1111_1111__1111
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1945,6 +1951,7 @@ impl TypeContents {
|
||||||
BoundSend => self.is_sendable(cx),
|
BoundSend => self.is_sendable(cx),
|
||||||
BoundSized => self.is_sized(cx),
|
BoundSized => self.is_sized(cx),
|
||||||
BoundPod => self.is_pod(cx),
|
BoundPod => self.is_pod(cx),
|
||||||
|
BoundShare => self.is_sharable(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,6 +1971,10 @@ impl TypeContents {
|
||||||
!self.intersects(TC::Nonsendable)
|
!self.intersects(TC::Nonsendable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_sharable(&self, _: &ctxt) -> bool {
|
||||||
|
!self.intersects(TC::Nonsharable)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn owns_managed(&self) -> bool {
|
pub fn owns_managed(&self) -> bool {
|
||||||
self.intersects(TC::OwnsManaged)
|
self.intersects(TC::OwnsManaged)
|
||||||
}
|
}
|
||||||
|
@ -2284,6 +2295,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||||
tc | TC::Managed
|
tc | TC::Managed
|
||||||
} else if Some(did) == cx.lang_items.no_pod_bound() {
|
} else if Some(did) == cx.lang_items.no_pod_bound() {
|
||||||
tc | TC::OwnsAffine
|
tc | TC::OwnsAffine
|
||||||
|
} else if Some(did) == cx.lang_items.no_share_bound() {
|
||||||
|
tc | TC::ReachesNoShare
|
||||||
} else {
|
} else {
|
||||||
tc
|
tc
|
||||||
}
|
}
|
||||||
|
@ -2362,6 +2375,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||||
BoundFreeze => TC::Nonfreezable,
|
BoundFreeze => TC::Nonfreezable,
|
||||||
BoundSized => TC::Nonsized,
|
BoundSized => TC::Nonsized,
|
||||||
BoundPod => TC::Nonpod,
|
BoundPod => TC::Nonpod,
|
||||||
|
BoundShare => TC::Nonsharable,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return tc;
|
return tc;
|
||||||
|
|
|
@ -674,6 +674,7 @@ impl Repr for ty::ParamBounds {
|
||||||
ty::BoundFreeze => ~"Freeze",
|
ty::BoundFreeze => ~"Freeze",
|
||||||
ty::BoundSized => ~"Sized",
|
ty::BoundSized => ~"Sized",
|
||||||
ty::BoundPod => ~"Pod",
|
ty::BoundPod => ~"Pod",
|
||||||
|
ty::BoundShare => ~"Share",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for t in self.trait_bounds.iter() {
|
for t in self.trait_bounds.iter() {
|
||||||
|
@ -961,6 +962,7 @@ impl UserString for ty::BuiltinBound {
|
||||||
ty::BoundFreeze => ~"Freeze",
|
ty::BoundFreeze => ~"Freeze",
|
||||||
ty::BoundSized => ~"Sized",
|
ty::BoundSized => ~"Sized",
|
||||||
ty::BoundPod => ~"Pod",
|
ty::BoundPod => ~"Pod",
|
||||||
|
ty::BoundShare => ~"Share",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,22 @@ pub trait Pod {
|
||||||
// Empty.
|
// 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
|
/// Marker types are special types that are used with unsafe code to
|
||||||
/// inform the compiler of special constraints. Marker types should
|
/// inform the compiler of special constraints. Marker types should
|
||||||
/// only be needed when you are creating an abstraction that is
|
/// only be needed when you are creating an abstraction that is
|
||||||
|
@ -232,6 +248,13 @@ pub mod marker {
|
||||||
#[deriving(Eq,Clone)]
|
#[deriving(Eq,Clone)]
|
||||||
pub struct NoPod;
|
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
|
/// A type which is considered managed by the GC. This is typically
|
||||||
/// embedded in other types.
|
/// embedded in other types.
|
||||||
#[lang="managed_bound"]
|
#[lang="managed_bound"]
|
||||||
|
|
|
@ -20,7 +20,7 @@ generally useful to many Rust programs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Reexported core operators
|
// 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::{Add, Sub, Mul, Div, Rem, Neg, Not};
|
||||||
pub use ops::{BitAnd, BitOr, BitXor};
|
pub use ops::{BitAnd, BitOr, BitXor};
|
||||||
pub use ops::{Drop, Deref, DerefMut};
|
pub use ops::{Drop, Deref, DerefMut};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue