Skip to content

Commit 37154fb

Browse files
committed
Add a Share kind
Fixes #11781
1 parent a92dcb0 commit 37154fb

File tree

7 files changed

+76
-29
lines changed

7 files changed

+76
-29
lines changed

src/librustc/metadata/tydecode.rs

+3
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,9 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
603603
'P' => {
604604
param_bounds.builtin_bounds.add(ty::BoundPod);
605605
}
606+
'T' => {
607+
param_bounds.builtin_bounds.add(ty::BoundShare);
608+
}
606609
'I' => {
607610
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
608611
}

src/librustc/metadata/tyencode.rs

+1
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
410410
ty::BoundStatic => mywrite!(w, "O"),
411411
ty::BoundSized => mywrite!(w, "Z"),
412412
ty::BoundPod => mywrite!(w, "P"),
413+
ty::BoundShare => mywrite!(w, "T"),
413414
}
414415
}
415416

src/librustc/middle/lang_items.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
use driver::session::Session;
2424
use metadata::csearch::each_lang_item;
25-
use middle::ty::{BuiltinBound, BoundFreeze, BoundPod, BoundSend, BoundSized};
25+
use middle::ty;
2626
use syntax::ast;
2727
use syntax::ast_util::local_def;
2828
use syntax::attr::AttrMetaMethods;
@@ -82,15 +82,17 @@ impl LanguageItems {
8282
}
8383
}
8484

85-
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<BuiltinBound> {
85+
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
8686
if Some(id) == self.freeze_trait() {
87-
Some(BoundFreeze)
87+
Some(ty::BoundFreeze)
8888
} else if Some(id) == self.send_trait() {
89-
Some(BoundSend)
89+
Some(ty::BoundSend)
9090
} else if Some(id) == self.sized_trait() {
91-
Some(BoundSized)
91+
Some(ty::BoundSized)
9292
} else if Some(id) == self.pod_trait() {
93-
Some(BoundPod)
93+
Some(ty::BoundPod)
94+
} else if Some(id) == self.share_trait() {
95+
Some(ty::BoundShare)
9496
} else {
9597
None
9698
}
@@ -213,6 +215,7 @@ lets_do_this! {
213215
SendTraitLangItem, "send", send_trait;
214216
SizedTraitLangItem, "sized", sized_trait;
215217
PodTraitLangItem, "pod", pod_trait;
218+
ShareTraitLangItem, "share", share_trait;
216219

217220
DropTraitLangItem, "drop", drop_trait;
218221

@@ -274,5 +277,6 @@ lets_do_this! {
274277
NoFreezeItem, "no_freeze_bound", no_freeze_bound;
275278
NoSendItem, "no_send_bound", no_send_bound;
276279
NoPodItem, "no_pod_bound", no_pod_bound;
280+
NoShareItem, "no_share_bound", no_share_bound;
277281
ManagedItem, "managed_bound", managed_bound;
278282
}

src/librustc/middle/ty.rs

+36-22
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ pub enum BuiltinBound {
850850
BoundFreeze,
851851
BoundSized,
852852
BoundPod,
853+
BoundShare,
853854
}
854855

855856
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
@@ -862,6 +863,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
862863
set.add(BoundSend);
863864
set.add(BoundFreeze);
864865
set.add(BoundSized);
866+
set.add(BoundShare);
865867
set
866868
}
867869

@@ -1872,31 +1874,32 @@ macro_rules! def_type_content_sets(
18721874

18731875
def_type_content_sets!(
18741876
mod TC {
1875-
None = 0b0000__00000000__0000,
1877+
None = 0b0000_0000__0000_0000__0000,
18761878

18771879
// Things that are interior to the value (first nibble):
1878-
InteriorUnsized = 0b0000__00000000__0001,
1879-
// InteriorAll = 0b0000__00000000__1111,
1880+
InteriorUnsized = 0b0000_0000__0000_0000__0001,
1881+
// InteriorAll = 0b0000_0000__0000_0000__1111,
18801882

18811883
// Things that are owned by the value (second and third nibbles):
1882-
OwnsOwned = 0b0000__00000001__0000,
1883-
OwnsDtor = 0b0000__00000010__0000,
1884-
OwnsManaged /* see [1] below */ = 0b0000__00000100__0000,
1885-
OwnsAffine = 0b0000__00001000__0000,
1886-
OwnsAll = 0b0000__11111111__0000,
1884+
OwnsOwned = 0b0000_0000__0000_0001__0000,
1885+
OwnsDtor = 0b0000_0000__0000_0010__0000,
1886+
OwnsManaged /* see [1] below */ = 0b0000_0000__0000_0100__0000,
1887+
OwnsAffine = 0b0000_0000__0000_1000__0000,
1888+
OwnsAll = 0b0000_0000__1111_1111__0000,
18871889

18881890
// Things that are reachable by the value in any way (fourth nibble):
1889-
ReachesNonsendAnnot = 0b0001__00000000__0000,
1890-
ReachesBorrowed = 0b0010__00000000__0000,
1891-
// ReachesManaged /* see [1] below */ = 0b0100__00000000__0000,
1892-
ReachesMutable = 0b1000__00000000__0000,
1893-
ReachesAll = 0b1111__00000000__0000,
1891+
ReachesNonsendAnnot = 0b0000_0001__0000_0000__0000,
1892+
ReachesBorrowed = 0b0000_0010__0000_0000__0000,
1893+
// ReachesManaged /* see [1] below */ = 0b0000_0100__0000_0000__0000,
1894+
ReachesMutable = 0b0000_1000__0000_0000__0000,
1895+
ReachesNoShare = 0b0001_0000__0000_0000__0000,
1896+
ReachesAll = 0b0001_1111__0000_0000__0000,
18941897

18951898
// Things that cause values to *move* rather than *copy*
1896-
Moves = 0b0000__00001011__0000,
1899+
Moves = 0b0000_0000__0000_1011__0000,
18971900

18981901
// Things that mean drop glue is necessary
1899-
NeedsDrop = 0b0000__00000111__0000,
1902+
NeedsDrop = 0b0000_0000__0000_0111__0000,
19001903

19011904
// Things that prevent values from being sent
19021905
//
@@ -1905,31 +1908,34 @@ def_type_content_sets!(
19051908
// both ReachesManaged and OwnsManaged so that when
19061909
// a parameter has a bound T:Send, we are able to deduce
19071910
// that it neither reaches nor owns a managed pointer.
1908-
Nonsendable = 0b0111__00000100__0000,
1911+
Nonsendable = 0b0000_0111__0000_0100__0000,
19091912

19101913
// Things that prevent values from being considered freezable
1911-
Nonfreezable = 0b1000__00000000__0000,
1914+
Nonfreezable = 0b0000_1000__0000_0000__0000,
19121915

19131916
// Things that prevent values from being considered 'static
1914-
Nonstatic = 0b0010__00000000__0000,
1917+
Nonstatic = 0b0000_0010__0000_0000__0000,
19151918

19161919
// Things that prevent values from being considered sized
1917-
Nonsized = 0b0000__00000000__0001,
1920+
Nonsized = 0b0000_0000__0000_0000__0001,
1921+
1922+
// Things that prevent values from being shared
1923+
Nonsharable = 0b0001_0000__0000_0000__0000,
19181924

19191925
// Things that make values considered not POD (would be same
19201926
// as `Moves`, but for the fact that managed data `@` is
19211927
// not considered POD)
1922-
Nonpod = 0b0000__00001111__0000,
1928+
Nonpod = 0b0000_0000__0000_1111__0000,
19231929

19241930
// Bits to set when a managed value is encountered
19251931
//
19261932
// [1] Do not set the bits TC::OwnsManaged or
19271933
// TC::ReachesManaged directly, instead reference
19281934
// TC::Managed to set them both at once.
1929-
Managed = 0b0100__00000100__0000,
1935+
Managed = 0b0000_0100__0000_0100__0000,
19301936

19311937
// All bits
1932-
All = 0b1111__11111111__1111
1938+
All = 0b1111_1111__1111_1111__1111
19331939
}
19341940
)
19351941

@@ -1945,6 +1951,7 @@ impl TypeContents {
19451951
BoundSend => self.is_sendable(cx),
19461952
BoundSized => self.is_sized(cx),
19471953
BoundPod => self.is_pod(cx),
1954+
BoundShare => self.is_sharable(cx),
19481955
}
19491956
}
19501957

@@ -1964,6 +1971,10 @@ impl TypeContents {
19641971
!self.intersects(TC::Nonsendable)
19651972
}
19661973

1974+
pub fn is_sharable(&self, _: &ctxt) -> bool {
1975+
!self.intersects(TC::Nonsharable)
1976+
}
1977+
19671978
pub fn owns_managed(&self) -> bool {
19681979
self.intersects(TC::OwnsManaged)
19691980
}
@@ -2284,6 +2295,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
22842295
tc | TC::Managed
22852296
} else if Some(did) == cx.lang_items.no_pod_bound() {
22862297
tc | TC::OwnsAffine
2298+
} else if Some(did) == cx.lang_items.no_share_bound() {
2299+
tc | TC::ReachesNoShare
22872300
} else {
22882301
tc
22892302
}
@@ -2362,6 +2375,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
23622375
BoundFreeze => TC::Nonfreezable,
23632376
BoundSized => TC::Nonsized,
23642377
BoundPod => TC::Nonpod,
2378+
BoundShare => TC::Nonsharable,
23652379
};
23662380
});
23672381
return tc;

src/librustc/util/ppaux.rs

+2
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ impl Repr for ty::ParamBounds {
674674
ty::BoundFreeze => ~"Freeze",
675675
ty::BoundSized => ~"Sized",
676676
ty::BoundPod => ~"Pod",
677+
ty::BoundShare => ~"Share",
677678
});
678679
}
679680
for t in self.trait_bounds.iter() {
@@ -961,6 +962,7 @@ impl UserString for ty::BuiltinBound {
961962
ty::BoundFreeze => ~"Freeze",
962963
ty::BoundSized => ~"Sized",
963964
ty::BoundPod => ~"Pod",
965+
ty::BoundShare => ~"Share",
964966
}
965967
}
966968
}

src/libstd/kinds.rs

+23
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ pub trait Pod {
4646
// Empty.
4747
}
4848

49+
/// Types that can be safely shared between threads, hence thread-safe.
50+
#[cfg(stage0)]
51+
pub trait Share {
52+
// Empty
53+
}
54+
55+
#[cfg(stage0)]
56+
impl<T> Share for T {}
57+
58+
/// Types that can be safely shared between threads, hence thread-safe.
59+
#[cfg(not(stage0))]
60+
#[lang="share"]
61+
pub trait Share {
62+
// Empty
63+
}
64+
4965
/// Marker types are special types that are used with unsafe code to
5066
/// inform the compiler of special constraints. Marker types should
5167
/// only be needed when you are creating an abstraction that is
@@ -232,6 +248,13 @@ pub mod marker {
232248
#[deriving(Eq,Clone)]
233249
pub struct NoPod;
234250

251+
/// A type which is considered "not sharable", meaning that
252+
/// its contents are not threadsafe, hence they cannot be
253+
/// shared between tasks.
254+
#[lang="no_share_bound"]
255+
#[deriving(Eq,Clone)]
256+
pub struct NoShare;
257+
235258
/// A type which is considered managed by the GC. This is typically
236259
/// embedded in other types.
237260
#[lang="managed_bound"]

src/libstd/prelude.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ generally useful to many Rust programs.
2020
*/
2121

2222
// Reexported core operators
23-
pub use kinds::{Freeze, Pod, Send, Sized};
23+
pub use kinds::{Freeze, Pod, Send, Sized, Share};
2424
pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
2525
pub use ops::{BitAnd, BitOr, BitXor};
2626
pub use ops::{Drop, Deref, DerefMut};

0 commit comments

Comments
 (0)