Rename Share to Sync

This leaves the `Share` trait at `std::kinds` via a `#[deprecated]` `pub use`
statement, but the `NoShare` struct is no longer part of `std::kinds::marker`
due to #12660 (the build cannot bootstrap otherwise).

All code referencing the `Share` trait should now reference the `Sync` trait,
and all code referencing the `NoShare` type should now reference the `NoSync`
type. The functionality and meaning of this trait have not changed, only the
naming.

Closes #16281
[breaking-change]
This commit is contained in:
Alex Crichton 2014-08-05 16:40:04 -07:00
parent b09a02b415
commit 1f760d5d1a
59 changed files with 199 additions and 190 deletions

View file

@ -50,15 +50,15 @@ non-deterministic behavior. Rust provides the tools to make using a GC
possible and even pleasant, but it should not be a requirement for
implementing the language.
## Non-`Share` `static mut` is unsafe
## Non-`Sync` `static mut` is unsafe
Types which are [`Share`][share] are thread-safe when multiple shared
references to them are used concurrently. Types which are not `Share` are not
Types which are [`Sync`][sync] are thread-safe when multiple shared
references to them are used concurrently. Types which are not `Sync` are not
thread-safe, and thus when used in a global require unsafe code to use.
[share]: http://doc.rust-lang.org/core/kinds/trait.Share.html
[sync]: http://doc.rust-lang.org/core/kinds/trait.Sync.html
### If mutable static items that implement `Share` are safe, why is taking &mut SHARABLE unsafe?
### If mutable static items that implement `Sync` are safe, why is taking &mut SHARABLE unsafe?
Having multiple aliasing `&mut T`s is never allowed. Due to the nature of
globals, the borrow checker cannot possibly ensure that a static obeys the

View file

@ -699,10 +699,10 @@ Other features provided by lang items include:
- stack unwinding and general failure; the `eh_personality`, `fail_`
and `fail_bounds_checks` lang items.
- the traits in `std::kinds` used to indicate types that satisfy
various kinds; lang items `send`, `share` and `copy`.
various kinds; lang items `send`, `sync` and `copy`.
- the marker types and variance indicators found in
`std::kinds::markers`; lang items `covariant_type`,
`contravariant_lifetime`, `no_share_bound`, etc.
`contravariant_lifetime`, `no_sync_bound`, etc.
Lang items are loaded lazily by the compiler; e.g. if one never uses
`Box` then there is no need to define functions for `exchange_malloc`

View file

@ -2111,7 +2111,7 @@ A complete list of the built-in language items follows:
: Has a size known at compile time.
* `copy`
: Types that do not move ownership when used by-value.
* `share`
* `sync`
: Able to be safely shared between tasks when aliased.
* `drop`
: Have destructors.
@ -2191,8 +2191,8 @@ These types help drive the compiler's analysis
: This type does not implement "send", even if eligible
* `no_copy_bound`
: This type does not implement "copy", even if eligible
* `no_share_bound`
: This type does not implement "share", even if eligible
* `no_sync_bound`
: This type does not implement "sync", even if eligible
* `managed_bound`
: This type implements "managed"

View file

@ -2196,7 +2196,7 @@ and may not be overridden:
Types are sendable
unless they contain references.
* `Share` - Types that are *threadsafe*.
* `Sync` - Types that are *threadsafe*.
These are types that are safe to be used across several threads with access to
a `&T` pointer. `Mutex<T>` is an example of a *sharable* type with internal mutable data.
@ -2250,7 +2250,7 @@ We say that the `Printable` trait _provides_ a `print` method with the
given signature. This means that we can call `print` on an argument
of any type that implements the `Printable` trait.
Rust's built-in `Send` and `Share` types are examples of traits that
Rust's built-in `Send` and `Sync` types are examples of traits that
don't provide any methods.
Traits may be implemented for specific types with [impls]. An impl for
@ -2535,7 +2535,7 @@ select the method to call at runtime.
This usage of traits is similar to Java interfaces.
There are some built-in bounds, such as `Send` and `Share`, which are properties
There are some built-in bounds, such as `Send` and `Sync`, which are properties
of the components of types. By design, trait objects don't know the exact type
of their contents and so the compiler cannot reason about those properties.
@ -2548,7 +2548,7 @@ trait Foo {}
trait Bar<T> {}
fn sendable_foo(f: Box<Foo + Send>) { /* ... */ }
fn shareable_bar<T: Share>(b: &Bar<T> + Share) { /* ... */ }
fn sync_bar<T: Sync>(b: &Bar<T> + Sync) { /* ... */ }
~~~
When no colon is specified (such as the type `Box<Foo>`), it is inferred that the

View file

@ -76,7 +76,7 @@ syn keyword rustType f64 i8 i16 i32 i64 str Self
" to make it easy to update.
" Core operators {{{3
syn keyword rustTrait Copy Send Sized Share
syn keyword rustTrait Copy Send Sized Sync
syn keyword rustTrait Add Sub Mul Div Rem Neg Not
syn keyword rustTrait BitAnd BitOr BitXor
syn keyword rustTrait Drop Deref DerefMut

View file

@ -15,7 +15,7 @@
use core::atomic;
use core::clone::Clone;
use core::kinds::{Share, Send};
use core::kinds::{Sync, Send};
use core::mem::{min_align_of, size_of, drop};
use core::mem;
use core::ops::{Drop, Deref};
@ -76,7 +76,7 @@ struct ArcInner<T> {
data: T,
}
impl<T: Share + Send> Arc<T> {
impl<T: Sync + Send> Arc<T> {
/// Create an atomically reference counted wrapper.
#[inline]
#[stable]
@ -95,8 +95,8 @@ impl<T: Share + Send> Arc<T> {
fn inner(&self) -> &ArcInner<T> {
// This unsafety is ok because while this arc is alive we're guaranteed
// that the inner pointer is valid. Furthermore, we know that the
// `ArcInner` structure itself is `Share` because the inner data is
// `Share` as well, so we're ok loaning out an immutable pointer to
// `ArcInner` structure itself is `Sync` because the inner data is
// `Sync` as well, so we're ok loaning out an immutable pointer to
// these contents.
unsafe { &*self._ptr }
}
@ -115,7 +115,7 @@ impl<T: Share + Send> Arc<T> {
}
#[unstable = "waiting on stability of Clone"]
impl<T: Share + Send> Clone for Arc<T> {
impl<T: Sync + Send> Clone for Arc<T> {
/// Duplicate an atomically reference counted wrapper.
///
/// The resulting two `Arc` objects will point to the same underlying data
@ -140,14 +140,14 @@ impl<T: Share + Send> Clone for Arc<T> {
}
#[experimental = "Deref is experimental."]
impl<T: Send + Share> Deref<T> for Arc<T> {
impl<T: Send + Sync> Deref<T> for Arc<T> {
#[inline]
fn deref(&self) -> &T {
&self.inner().data
}
}
impl<T: Send + Share + Clone> Arc<T> {
impl<T: Send + Sync + Clone> Arc<T> {
/// Acquires a mutable pointer to the inner contents by guaranteeing that
/// the reference count is one (no sharing is possible).
///
@ -175,7 +175,7 @@ impl<T: Send + Share + Clone> Arc<T> {
#[unsafe_destructor]
#[experimental = "waiting on stability of Drop"]
impl<T: Share + Send> Drop for Arc<T> {
impl<T: Sync + Send> Drop for Arc<T> {
fn drop(&mut self) {
// This structure has #[unsafe_no_drop_flag], so this drop glue may run
// more than once (but it is guaranteed to be zeroed after the first if
@ -219,7 +219,7 @@ impl<T: Share + Send> Drop for Arc<T> {
}
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Weak<T> {
impl<T: Sync + Send> Weak<T> {
/// Attempts to upgrade this weak reference to a strong reference.
///
/// This method will fail to upgrade this reference if the strong reference
@ -245,7 +245,7 @@ impl<T: Share + Send> Weak<T> {
}
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Clone for Weak<T> {
impl<T: Sync + Send> Clone for Weak<T> {
#[inline]
fn clone(&self) -> Weak<T> {
// See comments in Arc::clone() for why this is relaxed
@ -256,7 +256,7 @@ impl<T: Share + Send> Clone for Weak<T> {
#[unsafe_destructor]
#[experimental = "Weak pointers may not belong in this module."]
impl<T: Share + Send> Drop for Weak<T> {
impl<T: Sync + Send> Drop for Weak<T> {
fn drop(&mut self) {
// see comments above for why this check is here
if self._ptr.is_null() { return }

View file

@ -179,7 +179,7 @@ pub struct Rc<T> {
// field accesses of the contained type via Deref
_ptr: *mut RcBox<T>,
_nosend: marker::NoSend,
_noshare: marker::NoShare
_noshare: marker::NoSync
}
#[stable]
@ -199,7 +199,7 @@ impl<T> Rc<T> {
weak: Cell::new(1)
}),
_nosend: marker::NoSend,
_noshare: marker::NoShare
_noshare: marker::NoSync
}
}
}
@ -213,7 +213,7 @@ impl<T> Rc<T> {
Weak {
_ptr: self._ptr,
_nosend: marker::NoSend,
_noshare: marker::NoShare
_noshare: marker::NoSync
}
}
}
@ -348,7 +348,7 @@ impl<T> Clone for Rc<T> {
#[inline]
fn clone(&self) -> Rc<T> {
self.inc_strong();
Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
}
}
@ -412,7 +412,7 @@ pub struct Weak<T> {
// field accesses of the contained type via Deref
_ptr: *mut RcBox<T>,
_nosend: marker::NoSend,
_noshare: marker::NoShare
_noshare: marker::NoSync
}
#[experimental = "Weak pointers may not belong in this module."]
@ -423,7 +423,7 @@ impl<T> Weak<T> {
None
} else {
self.inc_strong();
Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare })
Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync })
}
}
}
@ -451,7 +451,7 @@ impl<T> Clone for Weak<T> {
#[inline]
fn clone(&self) -> Weak<T> {
self.inc_weak();
Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoShare }
Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
}
}

View file

@ -165,7 +165,7 @@ use option::{None, Option, Some};
#[unstable = "likely to be renamed; otherwise stable"]
pub struct Cell<T> {
value: UnsafeCell<T>,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
#[stable]
@ -174,7 +174,7 @@ impl<T:Copy> Cell<T> {
pub fn new(value: T) -> Cell<T> {
Cell {
value: UnsafeCell::new(value),
noshare: marker::NoShare,
noshare: marker::NoSync,
}
}
@ -213,7 +213,7 @@ pub struct RefCell<T> {
value: UnsafeCell<T>,
borrow: Cell<BorrowFlag>,
nocopy: marker::NoCopy,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
// Values [1, MAX-1] represent the number of `Ref` active
@ -230,7 +230,7 @@ impl<T> RefCell<T> {
value: UnsafeCell::new(value),
borrow: Cell::new(UNUSED),
nocopy: marker::NoCopy,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
}
@ -430,7 +430,7 @@ impl<'b, T> DerefMut<T> for RefMut<'b, T> {
///
/// struct NotThreadSafe<T> {
/// value: UnsafeCell<T>,
/// marker: marker::NoShare
/// marker: marker::NoSync
/// }
/// ```
///

View file

@ -20,6 +20,9 @@ by the compiler automatically for the types to which they apply.
*/
#[deprecated = "This has been renamed to Sync"]
pub use Share = self::Sync;
/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
@ -40,32 +43,32 @@ pub trait Copy {
/// Types that can be safely shared between tasks when aliased.
///
/// The precise definition is: a type `T` is `Share` if `&T` is
/// The precise definition is: a type `T` is `Sync` if `&T` is
/// thread-safe. In other words, there is no possibility of data races
/// when passing `&T` references between tasks.
///
/// As one would expect, primitive types like `u8` and `f64` are all
/// `Share`, and so are simple aggregate types containing them (like
/// tuples, structs and enums). More instances of basic `Share` types
/// `Sync`, and so are simple aggregate types containing them (like
/// tuples, structs and enums). More instances of basic `Sync` types
/// include "immutable" types like `&T` and those with simple
/// inherited mutability, such as `Box<T>`, `Vec<T>` and most other
/// collection types. (Generic parameters need to be `Share` for their
/// container to be `Share`.)
/// collection types. (Generic parameters need to be `Sync` for their
/// container to be `Sync`.)
///
/// A somewhat surprising consequence of the definition is `&mut T` is
/// `Share` (if `T` is `Share`) even though it seems that it might
/// `Sync` (if `T` is `Sync`) even though it seems that it might
/// provide unsynchronised mutation. The trick is a mutable reference
/// stored in an aliasable reference (that is, `& &mut T`) becomes
/// read-only, as if it were a `& &T`, hence there is no risk of a data
/// race.
///
/// Types that are not `Share` are those that have "interior
/// Types that are not `Sync` are those that have "interior
/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
/// in `std::cell`. These types allow for mutation of their contents
/// even when in an immutable, aliasable slot, e.g. the contents of
/// `&Cell<T>` can be `.set`, and do not ensure data races are
/// impossible, hence they cannot be `Share`. A higher level example
/// of a non-`Share` type is the reference counted pointer
/// impossible, hence they cannot be `Sync`. A higher level example
/// of a non-`Sync` type is the reference counted pointer
/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
/// reference, which modifies the reference counts in a non-atomic
/// way.
@ -73,18 +76,25 @@ pub trait Copy {
/// For cases when one does need thread-safe interior mutability,
/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
/// the `sync` crate do ensure that any mutation cannot cause data
/// races. Hence these types are `Share`.
/// races. Hence these types are `Sync`.
///
/// Users writing their own types with interior mutability (or anything
/// else that is not thread-safe) should use the `NoShare` marker type
/// else that is not thread-safe) should use the `NoSync` marker type
/// (from `std::kinds::marker`) to ensure that the compiler doesn't
/// consider the user-defined type to be `Share`. Any types with
/// consider the user-defined type to be `Sync`. Any types with
/// interior mutability must also use the `std::cell::UnsafeCell` wrapper
/// around the value(s) which can be mutated when behind a `&`
/// reference; not doing this is undefined behaviour (for example,
/// `transmute`-ing from `&T` to `&mut T` is illegal).
#[lang="sync"]
#[cfg(not(stage0))]
pub trait Sync {
// Empty
}
/// dox
#[lang="share"]
pub trait Share {
#[cfg(stage0)]
pub trait Sync {
// Empty
}
@ -94,7 +104,6 @@ pub trait Share {
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {
/// A marker type whose type parameter `T` is considered to be
/// covariant with respect to the type itself. This is (typically)
/// used to indicate that an instance of the type `T` is being stored
@ -266,12 +275,12 @@ pub mod marker {
#[deriving(PartialEq,Clone)]
pub struct NoCopy;
/// A type which is considered "not shareable", meaning that
/// A type which is considered "not sync", meaning that
/// its contents are not threadsafe, hence they cannot be
/// shared between tasks.
#[lang="no_share_bound"]
#[deriving(PartialEq,Clone)]
pub struct NoShare;
pub struct NoSync;
/// A type which is considered managed by the GC. This is typically
/// embedded in other types.

View file

@ -29,7 +29,7 @@
//! ```
// Reexported core operators
pub use kinds::{Copy, Send, Sized, Share};
pub use kinds::{Copy, Send, Sized, Sync};
pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop, Deref, DerefMut};

View file

@ -20,18 +20,18 @@ pub enum PopResult<T> {
pub fn queue<T: Send>() -> (Consumer<T>, Producer<T>) {
let a = Arc::new(mpsc::Queue::new());
(Consumer { inner: a.clone(), noshare: marker::NoShare },
Producer { inner: a, noshare: marker::NoShare })
(Consumer { inner: a.clone(), noshare: marker::NoSync },
Producer { inner: a, noshare: marker::NoSync })
}
pub struct Producer<T> {
inner: Arc<mpsc::Queue<T>>,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
pub struct Consumer<T> {
inner: Arc<mpsc::Queue<T>>,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
impl<T: Send> Consumer<T> {
@ -60,6 +60,6 @@ impl<T: Send> Producer<T> {
impl<T: Send> Clone for Producer<T> {
fn clone(&self) -> Producer<T> {
Producer { inner: self.inner.clone(), noshare: marker::NoShare }
Producer { inner: self.inner.clone(), noshare: marker::NoSync }
}
}

View file

@ -633,7 +633,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
param_bounds.builtin_bounds.add(ty::BoundCopy);
}
'T' => {
param_bounds.builtin_bounds.add(ty::BoundShare);
param_bounds.builtin_bounds.add(ty::BoundSync);
}
'I' => {
param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y))));

View file

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

View file

@ -13,7 +13,7 @@
// Language items are items that represent concepts intrinsic to the language
// itself. Examples are:
//
// * Traits that specify "kinds"; e.g. "Share", "Send".
// * Traits that specify "kinds"; e.g. "Sync", "Send".
//
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
//
@ -92,8 +92,8 @@ impl LanguageItems {
Some(ty::BoundSized)
} else if Some(id) == self.copy_trait() {
Some(ty::BoundCopy)
} else if Some(id) == self.share_trait() {
Some(ty::BoundShare)
} else if Some(id) == self.sync_trait() {
Some(ty::BoundSync)
} else {
None
}
@ -218,7 +218,7 @@ lets_do_this! {
SendTraitLangItem, "send", send_trait;
SizedTraitLangItem, "sized", sized_trait;
CopyTraitLangItem, "copy", copy_trait;
ShareTraitLangItem, "share", share_trait;
SyncTraitLangItem, "sync", sync_trait;
DropTraitLangItem, "drop", drop_trait;
@ -296,7 +296,7 @@ lets_do_this! {
NoSendItem, "no_send_bound", no_send_bound;
NoCopyItem, "no_copy_bound", no_copy_bound;
NoShareItem, "no_share_bound", no_share_bound;
NoSyncItem, "no_share_bound", no_share_bound;
ManagedItem, "managed_bound", managed_bound;
IteratorItem, "iterator", iterator;

View file

@ -499,7 +499,7 @@ impl TypeMap {
ty::BoundSend => unique_type_id.push_str("Send"),
ty::BoundSized => unique_type_id.push_str("Sized"),
ty::BoundCopy => unique_type_id.push_str("Copy"),
ty::BoundShare => unique_type_id.push_str("Share"),
ty::BoundSync => unique_type_id.push_str("Sync"),
};
unique_type_id.push_char('+');
}

View file

@ -833,7 +833,7 @@ pub enum BuiltinBound {
BoundSend,
BoundSized,
BoundCopy,
BoundShare,
BoundSync,
}
pub fn empty_builtin_bounds() -> BuiltinBounds {
@ -845,7 +845,7 @@ pub fn all_builtin_bounds() -> BuiltinBounds {
set.add(BoundStatic);
set.add(BoundSend);
set.add(BoundSized);
set.add(BoundShare);
set.add(BoundSync);
set
}
@ -1804,7 +1804,7 @@ def_type_content_sets!(
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,
ReachesNoSync = 0b0001_0000__0000_0000__0000,
ReachesAll = 0b0001_1111__0000_0000__0000,
// Things that cause values to *move* rather than *copy*
@ -1828,8 +1828,8 @@ def_type_content_sets!(
// Things that prevent values from being considered sized
Nonsized = 0b0000_0000__0000_0000__0001,
// Things that prevent values from being shared
Nonsharable = 0b0001_0000__0000_0000__0000,
// Things that prevent values from being sync
Nonsync = 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
@ -1855,7 +1855,7 @@ impl TypeContents {
BoundSend => self.is_sendable(cx),
BoundSized => self.is_sized(cx),
BoundCopy => self.is_copy(cx),
BoundShare => self.is_sharable(cx),
BoundSync => self.is_sync(cx),
}
}
@ -1875,8 +1875,8 @@ impl TypeContents {
!self.intersects(TC::Nonsendable)
}
pub fn is_sharable(&self, _: &ctxt) -> bool {
!self.intersects(TC::Nonsharable)
pub fn is_sync(&self, _: &ctxt) -> bool {
!self.intersects(TC::Nonsync)
}
pub fn owns_managed(&self) -> bool {
@ -2169,11 +2169,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
} else if Some(did) == cx.lang_items.no_copy_bound() {
tc | TC::OwnsAffine
} else if Some(did) == cx.lang_items.no_share_bound() {
tc | TC::ReachesNoShare
tc | TC::ReachesNoSync
} else if Some(did) == cx.lang_items.unsafe_type() {
// FIXME(#13231): This shouldn't be needed after
// opt-in built-in bounds are implemented.
(tc | TC::InteriorUnsafe) - TC::Nonsharable
(tc | TC::InteriorUnsafe) - TC::Nonsync
} else {
tc
}
@ -2237,7 +2237,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
BoundSend => TC::Nonsendable,
BoundSized => TC::Nonsized,
BoundCopy => TC::Noncopy,
BoundShare => TC::Nonsharable,
BoundSync => TC::Nonsync,
};
});
return tc;

View file

@ -646,7 +646,7 @@ impl Repr for ty::ParamBounds {
ty::BoundSend => "Send".to_string(),
ty::BoundSized => "Sized".to_string(),
ty::BoundCopy => "Copy".to_string(),
ty::BoundShare => "Share".to_string(),
ty::BoundSync => "Sync".to_string(),
});
}
for t in self.trait_bounds.iter() {
@ -931,7 +931,7 @@ impl UserString for ty::BuiltinBound {
ty::BoundSend => "Send".to_string(),
ty::BoundSized => "Sized".to_string(),
ty::BoundCopy => "Copy".to_string(),
ty::BoundShare => "Share".to_string(),
ty::BoundSync => "Sync".to_string(),
}
}
}

View file

@ -535,9 +535,9 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
ty::BoundCopy =>
(tcx.lang_items.copy_trait().unwrap(),
external_path("Copy", &empty)),
ty::BoundShare =>
(tcx.lang_items.share_trait().unwrap(),
external_path("Share", &empty)),
ty::BoundSync =>
(tcx.lang_items.sync_trait().unwrap(),
external_path("Sync", &empty)),
};
let fqn = csearch::get_item_path(tcx, did);
let fqn = fqn.move_iter().map(|i| i.to_string()).collect();

View file

@ -112,7 +112,7 @@ struct TLDValueBox<T> {
// refcount of 0 means uninitialized value, 1 means initialized, 2+ means
// borrowed.
// NB: we use UnsafeCell instead of Cell because Ref should be allowed to
// be Share. The only mutation occurs when a Ref is created or destroyed,
// be Sync. The only mutation occurs when a Ref is created or destroyed,
// so there's no issue with &Ref being thread-safe.
refcount: UnsafeCell<uint>
}

View file

@ -40,7 +40,7 @@
#![experimental]
// Reexported core operators
#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Share};
#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Sync};
#[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
#[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
#[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};

View file

@ -25,7 +25,7 @@
//!
//! [1]: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
//!
//! Atomic variables are safe to share between threads (they implement `Share`)
//! Atomic variables are safe to share between threads (they implement `Sync`)
//! but they do not themselves provide the mechanism for sharing. The most
//! common way to share an atomic variable is to put it into an `Arc` (an
//! atomically-reference-counted shared pointer).

View file

@ -375,7 +375,7 @@ pub struct Receiver<T> {
inner: UnsafeCell<Flavor<T>>,
receives: Cell<uint>,
// can't share in an arc
marker: marker::NoShare,
marker: marker::NoSync,
}
/// An iterator over messages on a receiver, this iterator will block
@ -393,7 +393,7 @@ pub struct Sender<T> {
inner: UnsafeCell<Flavor<T>>,
sends: Cell<uint>,
// can't share in an arc
marker: marker::NoShare,
marker: marker::NoSync,
}
/// The sending-half of Rust's synchronous channel type. This half can only be
@ -402,7 +402,7 @@ pub struct Sender<T> {
pub struct SyncSender<T> {
inner: Arc<UnsafeCell<sync::Packet<T>>>,
// can't share in an arc
marker: marker::NoShare,
marker: marker::NoSync,
}
/// This enumeration is the list of the possible reasons that try_recv could not
@ -537,7 +537,7 @@ impl<T: Send> Sender<T> {
Sender {
inner: UnsafeCell::new(inner),
sends: Cell::new(0),
marker: marker::NoShare,
marker: marker::NoSync,
}
}
@ -713,7 +713,7 @@ impl<T: Send> Drop for Sender<T> {
impl<T: Send> SyncSender<T> {
fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
SyncSender { inner: inner, marker: marker::NoShare }
SyncSender { inner: inner, marker: marker::NoSync }
}
/// Sends a value on this synchronous channel.
@ -801,7 +801,7 @@ impl<T: Send> Drop for SyncSender<T> {
impl<T: Send> Receiver<T> {
fn new(inner: Flavor<T>) -> Receiver<T> {
Receiver { inner: UnsafeCell::new(inner), receives: Cell::new(0), marker: marker::NoShare }
Receiver { inner: UnsafeCell::new(inner), receives: Cell::new(0), marker: marker::NoSync }
}
/// Blocks waiting for a value on this receiver

View file

@ -87,7 +87,7 @@ struct Deque<T> {
/// There may only be one worker per deque.
pub struct Worker<T> {
deque: Arc<Deque<T>>,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
/// The stealing half of the work-stealing deque. Stealers have access to the
@ -95,7 +95,7 @@ pub struct Worker<T> {
/// `steal` method.
pub struct Stealer<T> {
deque: Arc<Deque<T>>,
noshare: marker::NoShare,
noshare: marker::NoSync,
}
/// When stealing some data, this is an enumeration of the possible outcomes.
@ -153,8 +153,8 @@ impl<T: Send> BufferPool<T> {
pub fn deque(&self) -> (Worker<T>, Stealer<T>) {
let a = Arc::new(Deque::new(self.clone()));
let b = a.clone();
(Worker { deque: a, noshare: marker::NoShare },
Stealer { deque: b, noshare: marker::NoShare })
(Worker { deque: a, noshare: marker::NoSync },
Stealer { deque: b, noshare: marker::NoSync })
}
fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
@ -217,7 +217,7 @@ impl<T: Send> Stealer<T> {
impl<T: Send> Clone for Stealer<T> {
fn clone(&self) -> Stealer<T> {
Stealer { deque: self.deque.clone(), noshare: marker::NoShare }
Stealer { deque: self.deque.clone(), noshare: marker::NoSync }
}
}

View file

@ -298,7 +298,7 @@ pub struct RWLockReadGuard<'a, T> {
_guard: raw::RWLockReadGuard<'a>,
}
impl<T: Send + Share> RWLock<T> {
impl<T: Send + Sync> RWLock<T> {
/// Create a reader/writer lock with the supplied data.
pub fn new(user_data: T) -> RWLock<T> {
RWLock::new_with_condvars(user_data, 1)
@ -359,7 +359,7 @@ impl<T: Send + Share> RWLock<T> {
}
}
impl<'a, T: Send + Share> RWLockWriteGuard<'a, T> {
impl<'a, T: Send + Sync> RWLockWriteGuard<'a, T> {
/// Consumes this write lock token, returning a new read lock token.
///
/// This will allow pending readers to come into the lock.
@ -375,13 +375,13 @@ impl<'a, T: Send + Share> RWLockWriteGuard<'a, T> {
}
}
impl<'a, T: Send + Share> Deref<T> for RWLockReadGuard<'a, T> {
impl<'a, T: Send + Sync> Deref<T> for RWLockReadGuard<'a, T> {
fn deref<'a>(&'a self) -> &'a T { self._data }
}
impl<'a, T: Send + Share> Deref<T> for RWLockWriteGuard<'a, T> {
impl<'a, T: Send + Sync> Deref<T> for RWLockWriteGuard<'a, T> {
fn deref<'a>(&'a self) -> &'a T { &*self._data }
}
impl<'a, T: Send + Share> DerefMut<T> for RWLockWriteGuard<'a, T> {
impl<'a, T: Send + Sync> DerefMut<T> for RWLockWriteGuard<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self._data }
}

View file

@ -87,7 +87,7 @@ impl WaitQueue {
// The building-block used to make semaphores, mutexes, and rwlocks.
struct Sem<Q> {
lock: mutex::Mutex,
// n.b, we need Sem to be `Share`, but the WaitQueue type is not send/share
// n.b, we need Sem to be `Sync`, but the WaitQueue type is not send/share
// (for good reason). We have an internal invariant on this semaphore,
// however, that the queue is never accessed outside of a locked
// context.

View file

@ -208,7 +208,7 @@ pub static DUMMY_NODE_ID: NodeId = -1;
/// The AST represents all type param bounds as types.
/// typeck::collect::compute_bounds matches these against
/// the "special" built-in traits (see middle::lang_items) and
/// detects Copy, Send and Share.
/// detects Copy, Send and Sync.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum TyParamBound {
TraitTyParamBound(TraitRef),

View file

@ -27,7 +27,7 @@ pub fn expand_deriving_bound(cx: &mut ExtCtxt,
match tname.get() {
"Copy" => "Copy",
"Send" => "Send",
"Share" => "Share",
"Sync" => "Sync",
ref tname => {
cx.span_bug(span,
format!("expected built-in trait name but \

View file

@ -94,7 +94,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
"FromPrimitive" => expand!(primitive::expand_deriving_from_primitive),
"Send" => expand!(bounds::expand_deriving_bound),
"Share" => expand!(bounds::expand_deriving_bound),
"Sync" => expand!(bounds::expand_deriving_bound),
"Copy" => expand!(bounds::expand_deriving_bound),
ref tname => {

View file

@ -18,17 +18,17 @@ struct arc_destruct<T> {
}
#[unsafe_destructor]
impl<T: Share> Drop for arc_destruct<T> {
impl<T: Sync> Drop for arc_destruct<T> {
fn drop(&mut self) {}
}
fn arc_destruct<T: Share>(data: int) -> arc_destruct<T> {
fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
arc_destruct {
_data: data
}
}
fn arc<T: Share>(_data: T) -> arc_destruct<T> {
fn arc<T: Sync>(_data: T) -> arc_destruct<T> {
arc_destruct(0)
}

View file

@ -13,6 +13,6 @@
#![crate_type="lib"]
pub trait RequiresShare : Share { }
pub trait RequiresShare : Sync { }
pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
pub trait RequiresCopy : Copy { }

View file

@ -11,12 +11,12 @@
// Test for traits that inherit from multiple builtin kinds at once,
// testing that all such kinds must be present on implementing types.
trait Foo : Send+Share { }
trait Foo : Send+Sync { }
impl <T: Share> Foo for (T,) { } //~ ERROR cannot implement this trait
impl <T: Sync> Foo for (T,) { } //~ ERROR cannot implement this trait
impl <T: Send> Foo for (T,T) { } //~ ERROR cannot implement this trait
impl <T: Send+Share> Foo for (T,T,T) { } // (ok)
impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
fn main() { }

View file

@ -19,8 +19,8 @@ use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
struct X<T>(T);
impl <T:Share> RequiresShare for X<T> { }
impl <T:Sync> RequiresShare for X<T> { }
impl <T:Share> RequiresRequiresShareAndSend for X<T> { } //~ ERROR cannot implement this trait
impl <T:Sync> RequiresRequiresShareAndSend for X<T> { } //~ ERROR cannot implement this trait
fn main() { }

View file

@ -11,13 +11,13 @@
// Tests (negatively) the ability for the Self type in default methods
// to use capabilities granted by builtin kinds as supertraits.
trait Foo : Share {
trait Foo : Sync {
fn foo(self, mut chan: Sender<Self>) {
chan.send(self); //~ ERROR does not fulfill `Send`
}
}
impl <T: Share> Foo for T { }
impl <T: Sync> Foo for T { }
fn main() {
let (tx, rx) = channel();

View file

@ -12,6 +12,6 @@
trait Foo : Send { }
impl <T: Share> Foo for T { } //~ ERROR cannot implement this trait
impl <T: Sync> Foo for T { } //~ ERROR cannot implement this trait
fn main() { }

View file

@ -12,7 +12,7 @@
fn take_any(_: ||:) {
}
fn take_const_owned(_: ||:Share+Send) {
fn take_const_owned(_: ||:Sync+Send) {
}
fn give_any(f: ||:) {
@ -21,7 +21,7 @@ fn give_any(f: ||:) {
fn give_owned(f: ||:Send) {
take_any(f);
take_const_owned(f); //~ ERROR expected bounds `Send+Share` but found bounds `Send`
take_const_owned(f); //~ ERROR expected bounds `Send+Sync` but found bounds `Send`
}
fn main() {}

View file

@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn test<T: Share>() {}
fn test<T: Sync>() {}
fn main() {
test::<Sender<int>>(); //~ ERROR: does not fulfill `Share`
test::<Receiver<int>>(); //~ ERROR: does not fulfill `Share`
test::<Sender<int>>(); //~ ERROR: does not fulfill `Share`
test::<Sender<int>>(); //~ ERROR: does not fulfill `Sync`
test::<Receiver<int>>(); //~ ERROR: does not fulfill `Sync`
test::<Sender<int>>(); //~ ERROR: does not fulfill `Sync`
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[deriving(Share(Bad),Send,Copy)]
#[deriving(Sync(Bad),Send,Copy)]
//~^ ERROR unexpected value in deriving, expected a trait
struct Test;

View file

@ -20,7 +20,7 @@ struct E {
}
impl A for E {
fn b<F: Share, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Share`
fn b<F: Sync, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Sync`
}
fn main() {}

View file

@ -10,9 +10,9 @@
use std::kinds::marker;
fn foo<P: Share>(p: P) { }
fn foo<P: Sync>(p: P) { }
fn main()
{
foo(marker::NoShare); //~ ERROR does not fulfill `Share`
foo(marker::NoSync); //~ ERROR does not fulfill `Sync`
}

View file

@ -10,9 +10,9 @@
use std::cell::RefCell;
fn f<T: Share>(_: T) {}
fn f<T: Sync>(_: T) {}
fn main() {
let x = RefCell::new(0i);
f(x); //~ ERROR: which does not fulfill `Share`
f(x); //~ ERROR: which does not fulfill `Sync`
}

View file

@ -13,11 +13,11 @@
use std::kinds::marker;
enum Foo { A(marker::NoShare) }
enum Foo { A(marker::NoSync) }
fn bar<T: Share>(_: T) {}
fn bar<T: Sync>(_: T) {}
fn main() {
let x = A(marker::NoShare);
let x = A(marker::NoSync);
bar(&x); //~ ERROR type parameter with an incompatible type
}

View file

@ -10,13 +10,13 @@
use std::kinds::marker;
enum Foo { A(marker::NoShare) }
enum Foo { A(marker::NoSync) }
fn bar<T: Share>(_: T) {}
fn bar<T: Sync>(_: T) {}
fn main() {
let x = A(marker::NoShare);
let x = A(marker::NoSync);
bar(x);
//~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
// which does not fulfill `Share`
// which does not fulfill `Sync`
}

View file

@ -11,11 +11,11 @@
use std::rc::Rc;
use std::cell::RefCell;
fn bar<T: Share>(_: T) {}
fn bar<T: Sync>(_: T) {}
fn main() {
let x = Rc::new(RefCell::new(5i));
bar(x);
//~^ ERROR instantiating a type parameter with an incompatible type
// `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Share`
// `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Sync`
}

View file

@ -10,13 +10,13 @@
use std::kinds::marker;
struct Foo { a: int, m: marker::NoShare }
struct Foo { a: int, m: marker::NoSync }
fn bar<T: Share>(_: T) {}
fn bar<T: Sync>(_: T) {}
fn main() {
let x = Foo { a: 5, m: marker::NoShare };
let x = Foo { a: 5, m: marker::NoSync };
bar(x);
//~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
// which does not fulfill `Share`
// which does not fulfill `Sync`
}

View file

@ -9,7 +9,7 @@
// except according to those terms.
fn is_send<T: Send>() {}
fn is_freeze<T: Share>() {}
fn is_freeze<T: Sync>() {}
fn is_static<T: 'static>() {}
fn main() {

View file

@ -15,7 +15,7 @@ trait Foo {
fn a(_x: Box<Foo+Send>) {
}
fn c(x: Box<Foo+Share+Send>) {
fn c(x: Box<Foo+Sync+Send>) {
a(x);
}

View file

@ -19,11 +19,11 @@ fn a(_x: Box<Foo+Send>) {
fn b(_x: &'static Foo) { // should be same as &'static Foo+'static
}
fn c(x: Box<Foo+Share>) {
fn c(x: Box<Foo+Sync>) {
a(x); //~ ERROR expected bounds `Send`
}
fn d(x: &'static Foo+Share) {
fn d(x: &'static Foo+Sync) {
b(x); //~ ERROR expected bounds `'static`
}

View file

@ -8,36 +8,36 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Verify that UnsafeCell is *always* share regardles `T` is share.
// Verify that UnsafeCell is *always* sync regardles `T` is sync.
// ignore-tidy-linelength
use std::cell::UnsafeCell;
use std::kinds::marker;
struct MyShare<T> {
struct MySync<T> {
u: UnsafeCell<T>
}
struct NoShare {
m: marker::NoShare
struct NoSync {
m: marker::NoSync
}
fn test<T: Share>(s: T){
fn test<T: Sync>(s: T){
}
fn main() {
let us = UnsafeCell::new(MyShare{u: UnsafeCell::new(0i)});
let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0i)});
test(us);
let uns = UnsafeCell::new(NoShare{m: marker::NoShare});
let uns = UnsafeCell::new(NoSync{m: marker::NoSync});
test(uns);
let ms = MyShare{u: uns};
let ms = MySync{u: uns};
test(ms);
let ns = NoShare{m: marker::NoShare};
let ns = NoSync{m: marker::NoSync};
test(ns);
//~^ ERROR instantiating a type parameter with an incompatible type `NoShare`, which does not fulfill `Share`
//~^ ERROR instantiating a type parameter with an incompatible type `NoSync`, which does not fulfill `Sync`
}

View file

@ -14,11 +14,11 @@
trait Tr { }
impl Tr for int { }
fn foo(x: Box<Tr+ Share>) -> Box<Tr+ Share> { x }
fn foo(x: Box<Tr+ Sync>) -> Box<Tr+ Sync> { x }
fn main() {
let x: Box<Tr+ Share>;
let x: Box<Tr+ Sync>;
box() 1i as Box<Tr+ Share>;
box() 1i as Box<Tr+ Sync>;
}

View file

@ -20,8 +20,8 @@ use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
#[deriving(PartialEq)]
struct X<T>(T);
impl <T: Share> RequiresShare for X<T> { }
impl <T: Share+Send> RequiresRequiresShareAndSend for X<T> { }
impl <T: Sync> RequiresShare for X<T> { }
impl <T: Sync+Send> RequiresRequiresShareAndSend for X<T> { }
fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
chan.send(val);

View file

@ -19,9 +19,9 @@ use trait_superkinds_in_metadata::{RequiresCopy};
struct X<T>(T);
impl <T:Share> RequiresShare for X<T> { }
impl <T:Sync> RequiresShare for X<T> { }
impl <T:Share+Send> RequiresRequiresShareAndSend for X<T> { }
impl <T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
impl <T:Copy> RequiresCopy for X<T> { }

View file

@ -28,11 +28,11 @@ struct Foo<'a> {
a: ||: 'a,
b: ||: 'static,
c: <'b>||: 'a,
d: ||: 'a + Share,
e: <'b>|int|: 'a + Share -> &'b f32,
d: ||: 'a + Sync,
e: <'b>|int|: 'a + Sync -> &'b f32,
f: proc(),
g: proc(): 'static + Share,
h: proc<'b>(int): Share -> &'b f32,
g: proc(): 'static + Sync,
h: proc<'b>(int): Sync -> &'b f32,
}
fn f<'a>(a: &'a int, f: <'b>|&'b int| -> &'b int) -> &'a int {
@ -54,14 +54,14 @@ fn bar<'b>() {
foo::<|| -> ()>();
foo::<||:>();
foo::<||:'b>();
foo::<||:'b + Share>();
foo::<||:Share>();
foo::< <'a>|int, f32, &'a int|:'b + Share -> &'a int>();
foo::<||:'b + Sync>();
foo::<||:Sync>();
foo::< <'a>|int, f32, &'a int|:'b + Sync -> &'a int>();
foo::<proc()>();
foo::<proc() -> ()>();
foo::<proc():'static>();
foo::<proc():Share>();
foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
foo::<proc():Sync>();
foo::<proc<'a>(int, f32, &'a int):'static + Sync -> &'a int>();
foo::<<'a>||>();

View file

@ -12,7 +12,7 @@
// are const.
fn foo<T: Share>(x: T) -> T { x }
fn foo<T: Sync>(x: T) -> T { x }
struct F { field: int }

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[deriving(Share,Send,Copy)]
#[deriving(Sync,Send,Copy)]
struct Test;
pub fn main() {}

View file

@ -12,7 +12,7 @@
// than the traits require.
trait A {
fn b<C:Share,D>(x: C) -> C;
fn b<C:Sync,D>(x: C) -> C;
}
struct E {

View file

@ -20,7 +20,7 @@ mod foo {
}
fn foo1<T>(_: &A<T> + Send) {}
fn foo2<T>(_: Box<A<T> + Send + Share>) {}
fn foo2<T>(_: Box<A<T> + Send + Sync>) {}
fn foo3<T>(_: Box<B<int, uint> + 'static>) {}
fn foo4<'a, T>(_: Box<C<'a, T> + 'static + Send>) {}
fn foo5<'a, T>(_: Box<foo::D<'a, T> + 'static + Send>) {}

View file

@ -12,18 +12,18 @@ fn foo<T>() {}
fn bar<T>(_: T) {}
fn is_send<T: Send>() {}
fn is_freeze<T: Share>() {}
fn is_freeze<T: Sync>() {}
fn is_static<T: 'static>() {}
pub fn main() {
foo::<proc()>();
foo::<proc()>();
foo::<proc():Send>();
foo::<proc():Send + Share>();
foo::<proc():'static + Send + Share>();
foo::<proc():Send + Sync>();
foo::<proc():'static + Send + Sync>();
is_send::<proc():Send>();
is_freeze::<proc():Share>();
is_freeze::<proc():Sync>();
is_static::<proc():'static>();

View file

@ -15,7 +15,7 @@ trait Foo {
fn b(_x: Box<Foo+Send>) {
}
fn c(x: Box<Foo+Share+Send>) {
fn c(x: Box<Foo+Sync+Send>) {
e(x);
}

View file

@ -71,10 +71,10 @@ pub fn main() {
swim_speed: 998,
name: "alec_guinness".to_string(),
};
let arc = Arc::new(vec!(box catte as Box<Pet+Share+Send>,
box dogge1 as Box<Pet+Share+Send>,
box fishe as Box<Pet+Share+Send>,
box dogge2 as Box<Pet+Share+Send>));
let arc = Arc::new(vec!(box catte as Box<Pet+Sync+Send>,
box dogge1 as Box<Pet+Sync+Send>,
box fishe as Box<Pet+Sync+Send>,
box dogge2 as Box<Pet+Sync+Send>));
let (tx1, rx1) = channel();
let arc1 = arc.clone();
task::spawn(proc() { check_legs(arc1); tx1.send(()); });
@ -89,21 +89,21 @@ pub fn main() {
rx3.recv();
}
fn check_legs(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
fn check_legs(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
let mut legs = 0;
for pet in arc.iter() {
legs += pet.num_legs();
}
assert!(legs == 12);
}
fn check_names(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
fn check_names(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
for pet in arc.iter() {
pet.name(|name| {
assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
})
}
}
fn check_pedigree(arc: Arc<Vec<Box<Pet+Share+Send>>>) {
fn check_pedigree(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
for pet in arc.iter() {
assert!(pet.of_good_pedigree());
}