parent
a92dcb0828
commit
37154fb8b9
@ -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)));
|
||||
}
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"]
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user