diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 1abbf1307c1..157cc8cd0f0 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -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)));
             }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index 0934b6407fb..792fca5eca6 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -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"),
         }
     }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 3b322d02787..4e16683bcba 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -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;
 }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 61371cec49e..00ccadc68c6 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -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;
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 7c03c1dc45d..2b6c6825c7e 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -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",
         }
     }
 }
diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs
index da17119fd98..b44616421d1 100644
--- a/src/libstd/kinds.rs
+++ b/src/libstd/kinds.rs
@@ -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"]
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 0b1de74330d..f3a5bd3d3b5 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -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};