auto merge of #13076 : FlaPer87/rust/remove-freeze, r=alexcrichton
This PR removes the `Freeze` kind and the `NoFreeze` marker completely. Fixes #12577 cc @nikomatsakis r?
This commit is contained in:
commit
7e7a5e3d3e
@ -1019,7 +1019,7 @@ never invoking this behaviour or exposing an API making it possible for it to oc
|
||||
|
||||
* Data races
|
||||
* Dereferencing a null/dangling raw pointer
|
||||
* Mutating an immutable value/reference, if it is not marked as non-`Freeze`
|
||||
* Mutating an immutable value/reference
|
||||
* Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values) (uninitialized) memory
|
||||
* Breaking the [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
|
||||
with raw pointers (a subset of the rules used by C)
|
||||
@ -3434,10 +3434,6 @@ call to the method `make_string`.
|
||||
Types in Rust are categorized into kinds, based on various properties of the components of the type.
|
||||
The kinds are:
|
||||
|
||||
`Freeze`
|
||||
: Types of this kind are deeply immutable;
|
||||
they contain no mutable memory locations
|
||||
directly or indirectly via pointers.
|
||||
`Send`
|
||||
: Types of this kind can be safely sent between tasks.
|
||||
This kind includes scalars, owning pointers, owned closures, and
|
||||
|
@ -2099,10 +2099,6 @@ unless they contain managed boxes, managed closures, or references.
|
||||
These are types that are safe to be used across several threads with access to
|
||||
a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal mutable data.
|
||||
|
||||
* `Freeze` - Constant (immutable) types.
|
||||
These are types that do not contain anything intrinsically mutable.
|
||||
Intrinsically mutable values include `Cell` in the standard library.
|
||||
|
||||
* `'static` - Non-borrowed types.
|
||||
These are types that do not contain any data whose lifetime is bound to
|
||||
a particular stack frame. These are types that do not contain any
|
||||
@ -2152,7 +2148,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 `Freeze` types are examples of traits that
|
||||
Rust's built-in `Send` and `Share` types are examples of traits that
|
||||
don't provide any methods.
|
||||
|
||||
Traits may be implemented for specific types with [impls]. An impl for
|
||||
@ -2444,15 +2440,15 @@ Consequently, the trait objects themselves automatically fulfill their
|
||||
respective kind bounds. However, this default behavior can be overridden by
|
||||
specifying a list of bounds on the trait type, for example, by writing `~Trait:`
|
||||
(which indicates that the contents of the owned trait need not fulfill any
|
||||
bounds), or by writing `~Trait:Send+Freeze`, which indicates that in addition
|
||||
to fulfilling `Send`, contents must also fulfill `Freeze`, and as a consequence,
|
||||
the trait itself fulfills `Freeze`.
|
||||
bounds), or by writing `~Trait:Send+Share`, which indicates that in addition
|
||||
to fulfilling `Send`, contents must also fulfill `Share`, and as a consequence,
|
||||
the trait itself fulfills `Share`.
|
||||
|
||||
* `~Trait:Send` is equivalent to `~Trait`.
|
||||
* `&Trait:` is equivalent to `&Trait`.
|
||||
|
||||
Builtin kind bounds can also be specified on closure types in the same way (for
|
||||
example, by writing `fn:Freeze()`), and the default behaviours are the same as
|
||||
example, by writing `fn:Send()`), and the default behaviours are the same as
|
||||
for traits of the same storage class.
|
||||
|
||||
## Trait inheritance
|
||||
|
@ -37,7 +37,6 @@ use std::mem;
|
||||
use std::ptr::read;
|
||||
use std::cmp;
|
||||
use std::num;
|
||||
use std::kinds::marker;
|
||||
use std::rc::Rc;
|
||||
use std::rt::global_heap;
|
||||
use std::intrinsics::{TyDesc, get_tydesc};
|
||||
@ -90,7 +89,6 @@ pub struct Arena {
|
||||
priv head: Chunk,
|
||||
priv pod_head: Chunk,
|
||||
priv chunks: RefCell<@List<Chunk>>,
|
||||
priv no_freeze: marker::NoFreeze,
|
||||
}
|
||||
|
||||
impl Arena {
|
||||
@ -103,7 +101,6 @@ impl Arena {
|
||||
head: chunk(initial_size, false),
|
||||
pod_head: chunk(initial_size, true),
|
||||
chunks: RefCell::new(@Nil),
|
||||
no_freeze: marker::NoFreeze,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,9 +584,6 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
|
||||
'S' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundSend);
|
||||
}
|
||||
'K' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundFreeze);
|
||||
}
|
||||
'O' => {
|
||||
param_bounds.builtin_bounds.add(ty::BoundStatic);
|
||||
}
|
||||
|
@ -392,7 +392,6 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
|
||||
for bound in bs.builtin_bounds.iter() {
|
||||
match bound {
|
||||
ty::BoundSend => mywrite!(w, "S"),
|
||||
ty::BoundFreeze => mywrite!(w, "K"),
|
||||
ty::BoundStatic => mywrite!(w, "O"),
|
||||
ty::BoundSized => mywrite!(w, "Z"),
|
||||
ty::BoundPod => mywrite!(w, "P"),
|
||||
|
@ -30,20 +30,14 @@ use syntax::visit::Visitor;
|
||||
// kind is noncopyable. The noncopyable kind can be extended with any number
|
||||
// of the following attributes.
|
||||
//
|
||||
// send: Things that can be sent on channels or included in spawned closures.
|
||||
// freeze: Things thare are deeply immutable. They are guaranteed never to
|
||||
// change, and can be safely shared without copying between tasks.
|
||||
// Send: Things that can be sent on channels or included in spawned closures. It
|
||||
// includes scalar types as well as classes and unique types containing only
|
||||
// sendable types.
|
||||
// 'static: Things that do not contain references.
|
||||
//
|
||||
// Send includes scalar types as well as classes and unique types containing
|
||||
// only sendable types.
|
||||
//
|
||||
// Freeze include scalar types, things without non-const fields, and pointers
|
||||
// to freezable things.
|
||||
//
|
||||
// This pass ensures that type parameters are only instantiated with types
|
||||
// whose kinds are equal or less general than the way the type parameter was
|
||||
// annotated (with the `Send` or `Freeze` bound).
|
||||
// annotated (with the `Send` bound).
|
||||
//
|
||||
// It also verifies that noncopyable kinds are not copied. Sendability is not
|
||||
// applied, since none of our language primitives send. Instead, the sending
|
||||
|
@ -13,7 +13,7 @@
|
||||
// Language items are items that represent concepts intrinsic to the language
|
||||
// itself. Examples are:
|
||||
//
|
||||
// * Traits that specify "kinds"; e.g. "Freeze", "Send".
|
||||
// * Traits that specify "kinds"; e.g. "Share", "Send".
|
||||
//
|
||||
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
|
||||
//
|
||||
@ -82,9 +82,7 @@ impl LanguageItems {
|
||||
}
|
||||
|
||||
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
|
||||
if Some(id) == self.freeze_trait() {
|
||||
Some(ty::BoundFreeze)
|
||||
} else if Some(id) == self.send_trait() {
|
||||
if Some(id) == self.send_trait() {
|
||||
Some(ty::BoundSend)
|
||||
} else if Some(id) == self.sized_trait() {
|
||||
Some(ty::BoundSized)
|
||||
@ -210,7 +208,6 @@ pub fn collect_language_items(krate: &ast::Crate,
|
||||
|
||||
lets_do_this! {
|
||||
// Variant name, Name, Method name;
|
||||
FreezeTraitLangItem, "freeze", freeze_trait;
|
||||
SendTraitLangItem, "send", send_trait;
|
||||
SizedTraitLangItem, "sized", sized_trait;
|
||||
PodTraitLangItem, "pod", pod_trait;
|
||||
@ -275,7 +272,6 @@ lets_do_this! {
|
||||
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
|
||||
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
|
||||
|
||||
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;
|
||||
|
@ -838,7 +838,6 @@ pub type BuiltinBounds = EnumSet<BuiltinBound>;
|
||||
pub enum BuiltinBound {
|
||||
BoundStatic,
|
||||
BoundSend,
|
||||
BoundFreeze,
|
||||
BoundSized,
|
||||
BoundPod,
|
||||
BoundShare,
|
||||
@ -852,7 +851,6 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
|
||||
let mut set = EnumSet::empty();
|
||||
set.add(BoundStatic);
|
||||
set.add(BoundSend);
|
||||
set.add(BoundFreeze);
|
||||
set.add(BoundSized);
|
||||
set.add(BoundShare);
|
||||
set
|
||||
@ -1892,9 +1890,6 @@ def_type_content_sets!(
|
||||
// that it neither reaches nor owns a managed pointer.
|
||||
Nonsendable = 0b0000_0111__0000_0100__0000,
|
||||
|
||||
// Things that prevent values from being considered freezable
|
||||
Nonfreezable = 0b0000_1000__0000_0000__0000,
|
||||
|
||||
// Things that prevent values from being considered 'static
|
||||
Nonstatic = 0b0000_0010__0000_0000__0000,
|
||||
|
||||
@ -1929,7 +1924,6 @@ impl TypeContents {
|
||||
pub fn meets_bound(&self, cx: &ctxt, bb: BuiltinBound) -> bool {
|
||||
match bb {
|
||||
BoundStatic => self.is_static(cx),
|
||||
BoundFreeze => self.is_freezable(cx),
|
||||
BoundSend => self.is_sendable(cx),
|
||||
BoundSized => self.is_sized(cx),
|
||||
BoundPod => self.is_pod(cx),
|
||||
@ -1965,10 +1959,6 @@ impl TypeContents {
|
||||
self.intersects(TC::OwnsOwned)
|
||||
}
|
||||
|
||||
pub fn is_freezable(&self, _: &ctxt) -> bool {
|
||||
!self.intersects(TC::Nonfreezable)
|
||||
}
|
||||
|
||||
pub fn is_sized(&self, _: &ctxt) -> bool {
|
||||
!self.intersects(TC::Nonsized)
|
||||
}
|
||||
@ -2073,10 +2063,6 @@ pub fn type_is_sendable(cx: &ctxt, t: ty::t) -> bool {
|
||||
type_contents(cx, t).is_sendable(cx)
|
||||
}
|
||||
|
||||
pub fn type_is_freezable(cx: &ctxt, t: ty::t) -> bool {
|
||||
type_contents(cx, t).is_freezable(cx)
|
||||
}
|
||||
|
||||
pub fn type_interior_is_unsafe(cx: &ctxt, t: ty::t) -> bool {
|
||||
type_contents(cx, t).interior_unsafe()
|
||||
}
|
||||
@ -2132,7 +2118,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
cache.insert(ty_id, TC::None);
|
||||
|
||||
let result = match get(ty).sty {
|
||||
// Scalar and unique types are sendable, freezable, and durable
|
||||
// Scalar and unique types are sendable, and durable
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||
ty_bare_fn(_) | ty::ty_char => {
|
||||
TC::None
|
||||
@ -2270,9 +2256,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
did: ast::DefId,
|
||||
tc: TypeContents)
|
||||
-> TypeContents {
|
||||
if Some(did) == cx.lang_items.no_freeze_bound() {
|
||||
tc | TC::ReachesMutable
|
||||
} else if Some(did) == cx.lang_items.no_send_bound() {
|
||||
if Some(did) == cx.lang_items.no_send_bound() {
|
||||
tc | TC::ReachesNonsendAnnot
|
||||
} else if Some(did) == cx.lang_items.managed_bound() {
|
||||
tc | TC::Managed
|
||||
@ -2357,7 +2341,6 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
tc = tc - match bound {
|
||||
BoundStatic => TC::Nonstatic,
|
||||
BoundSend => TC::Nonsendable,
|
||||
BoundFreeze => TC::Nonfreezable,
|
||||
BoundSized => TC::Nonsized,
|
||||
BoundPod => TC::Nonpod,
|
||||
BoundShare => TC::Nonsharable,
|
||||
|
@ -976,8 +976,7 @@ pub fn ty_generics(ccx: &CrateCtxt,
|
||||
* Translate the AST's notion of ty param bounds (which are an
|
||||
* enum consisting of a newtyped Ty or a region) to ty's
|
||||
* notion of ty param bounds, which can either be user-defined
|
||||
* traits, or one of the two built-in traits (formerly known
|
||||
* as kinds): Freeze and Send.
|
||||
* traits, or the built-in trait (formerly known as kind): Send.
|
||||
*/
|
||||
|
||||
let mut param_bounds = ty::ParamBounds {
|
||||
|
@ -664,7 +664,6 @@ impl Repr for ty::ParamBounds {
|
||||
res.push(match b {
|
||||
ty::BoundStatic => ~"'static",
|
||||
ty::BoundSend => ~"Send",
|
||||
ty::BoundFreeze => ~"Freeze",
|
||||
ty::BoundSized => ~"Sized",
|
||||
ty::BoundPod => ~"Pod",
|
||||
ty::BoundShare => ~"Share",
|
||||
@ -952,7 +951,6 @@ impl UserString for ty::BuiltinBound {
|
||||
match *self {
|
||||
ty::BoundStatic => ~"'static",
|
||||
ty::BoundSend => ~"Send",
|
||||
ty::BoundFreeze => ~"Freeze",
|
||||
ty::BoundSized => ~"Sized",
|
||||
ty::BoundPod => ~"Pod",
|
||||
ty::BoundShare => ~"Share",
|
||||
|
@ -116,8 +116,8 @@ pub enum Implementor {
|
||||
///
|
||||
/// This structure purposefully does not implement `Clone` because it's intended
|
||||
/// to be a fairly large and expensive structure to clone. Instead this adheres
|
||||
/// to both `Send` and `Freeze` so it may be stored in a `Arc` instance and
|
||||
/// shared among the various rendering tasks.
|
||||
/// to `Send` so it may be stored in a `Arc` instance and shared among the various
|
||||
/// rendering tasks.
|
||||
pub struct Cache {
|
||||
/// Mapping of typaram ids to the name of the type parameter. This is used
|
||||
/// when pretty-printing a type (so pretty printing doesn't have to
|
||||
|
@ -22,8 +22,7 @@ use ty::Unsafe;
|
||||
/// A mutable memory location that admits only `Pod` data.
|
||||
pub struct Cell<T> {
|
||||
priv value: Unsafe<T>,
|
||||
priv marker1: marker::NoFreeze,
|
||||
priv marker2: marker::NoShare,
|
||||
priv noshare: marker::NoShare,
|
||||
}
|
||||
|
||||
impl<T:Pod> Cell<T> {
|
||||
@ -31,8 +30,7 @@ impl<T:Pod> Cell<T> {
|
||||
pub fn new(value: T) -> Cell<T> {
|
||||
Cell {
|
||||
value: Unsafe::new(value),
|
||||
marker1: marker::NoFreeze,
|
||||
marker2: marker::NoShare,
|
||||
noshare: marker::NoShare,
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,9 +71,8 @@ impl<T: fmt::Show> fmt::Show for Cell<T> {
|
||||
pub struct RefCell<T> {
|
||||
priv value: Unsafe<T>,
|
||||
priv borrow: BorrowFlag,
|
||||
priv marker1: marker::NoFreeze,
|
||||
priv marker2: marker::NoPod,
|
||||
priv marker3: marker::NoShare,
|
||||
priv nopod: marker::NoPod,
|
||||
priv noshare: marker::NoShare,
|
||||
}
|
||||
|
||||
// Values [1, MAX-1] represent the number of `Ref` active
|
||||
@ -88,10 +85,9 @@ impl<T> RefCell<T> {
|
||||
/// Create a new `RefCell` containing `value`
|
||||
pub fn new(value: T) -> RefCell<T> {
|
||||
RefCell {
|
||||
marker1: marker::NoFreeze,
|
||||
marker2: marker::NoPod,
|
||||
marker3: marker::NoShare,
|
||||
value: Unsafe::new(value),
|
||||
nopod: marker::NoPod,
|
||||
noshare: marker::NoShare,
|
||||
borrow: UNUSED,
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ pub struct Receiver<T> {
|
||||
priv inner: Flavor<T>,
|
||||
priv receives: Cell<uint>,
|
||||
// can't share in an arc
|
||||
priv marker: marker::NoFreeze,
|
||||
priv marker: marker::NoShare,
|
||||
}
|
||||
|
||||
/// An iterator over messages on a receiver, this iterator will block
|
||||
@ -307,7 +307,7 @@ pub struct Sender<T> {
|
||||
priv inner: Flavor<T>,
|
||||
priv sends: Cell<uint>,
|
||||
// can't share in an arc
|
||||
priv marker: marker::NoFreeze,
|
||||
priv marker: marker::NoShare,
|
||||
}
|
||||
|
||||
/// This enumeration is the list of the possible reasons that try_recv could not
|
||||
@ -340,7 +340,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
|
||||
|
||||
impl<T: Send> Sender<T> {
|
||||
fn my_new(inner: Flavor<T>) -> Sender<T> {
|
||||
Sender { inner: inner, sends: Cell::new(0), marker: marker::NoFreeze }
|
||||
Sender { inner: inner, sends: Cell::new(0), marker: marker::NoShare }
|
||||
}
|
||||
|
||||
/// Sends a value along this channel to be received by the corresponding
|
||||
@ -478,7 +478,7 @@ impl<T: Send> Drop for Sender<T> {
|
||||
|
||||
impl<T: Send> Receiver<T> {
|
||||
fn my_new(inner: Flavor<T>) -> Receiver<T> {
|
||||
Receiver { inner: inner, receives: Cell::new(0), marker: marker::NoFreeze }
|
||||
Receiver { inner: inner, receives: Cell::new(0), marker: marker::NoShare }
|
||||
}
|
||||
|
||||
/// Blocks waiting for a value on this receiver
|
||||
|
@ -66,7 +66,6 @@ pub struct Select {
|
||||
priv tail: *mut Handle<'static, ()>,
|
||||
priv next_id: Cell<uint>,
|
||||
priv marker1: marker::NoSend,
|
||||
priv marker2: marker::NoFreeze,
|
||||
}
|
||||
|
||||
/// A handle to a receiver which is currently a member of a `Select` set of
|
||||
@ -105,7 +104,6 @@ impl Select {
|
||||
pub fn new() -> Select {
|
||||
Select {
|
||||
marker1: marker::NoSend,
|
||||
marker2: marker::NoFreeze,
|
||||
head: 0 as *mut Handle<'static, ()>,
|
||||
tail: 0 as *mut Handle<'static, ()>,
|
||||
next_id: Cell::new(1),
|
||||
|
@ -26,12 +26,6 @@ pub trait Send {
|
||||
// empty.
|
||||
}
|
||||
|
||||
/// Types that are either immutable or have inherited mutability.
|
||||
#[lang="freeze"]
|
||||
pub trait Freeze {
|
||||
// empty.
|
||||
}
|
||||
|
||||
/// Types with a constant size known at compile-time.
|
||||
#[lang="sized"]
|
||||
pub trait Sized {
|
||||
@ -225,14 +219,6 @@ pub mod marker {
|
||||
#[deriving(Eq,Clone)]
|
||||
pub struct InvariantLifetime<'a>;
|
||||
|
||||
/// A type which is considered "not freezable", meaning that
|
||||
/// its contents could change even if stored in an immutable
|
||||
/// context or it is the referent of an `&T` pointer. This is
|
||||
/// typically embedded in other types, such as `Cell`.
|
||||
#[lang="no_freeze_bound"]
|
||||
#[deriving(Eq,Clone)]
|
||||
pub struct NoFreeze;
|
||||
|
||||
/// A type which is considered "not sendable", meaning that it cannot
|
||||
/// be safely sent between tasks, even if it is owned. This is
|
||||
/// typically embedded in other types, such as `Gc`, to ensure that
|
||||
|
@ -20,7 +20,7 @@ generally useful to many Rust programs.
|
||||
*/
|
||||
|
||||
// Reexported core operators
|
||||
pub use kinds::{Freeze, Pod, Send, Sized, Share};
|
||||
pub use kinds::{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};
|
||||
|
@ -162,7 +162,6 @@ struct MutexArcInner<T> { lock: Mutex, failed: bool, data: T }
|
||||
/// An Arc with mutable data protected by a blocking mutex.
|
||||
pub struct MutexArc<T> {
|
||||
priv x: UnsafeArc<MutexArcInner<T>>,
|
||||
priv marker: marker::NoFreeze,
|
||||
}
|
||||
|
||||
impl<T:Send> Clone for MutexArc<T> {
|
||||
@ -171,8 +170,7 @@ impl<T:Send> Clone for MutexArc<T> {
|
||||
fn clone(&self) -> MutexArc<T> {
|
||||
// NB: Cloning the underlying mutex is not necessary. Its reference
|
||||
// count would be exactly the same as the shared state's.
|
||||
MutexArc { x: self.x.clone(),
|
||||
marker: marker::NoFreeze, }
|
||||
MutexArc { x: self.x.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,8 +189,7 @@ impl<T:Send> MutexArc<T> {
|
||||
lock: Mutex::new_with_condvars(num_condvars),
|
||||
failed: false, data: user_data
|
||||
};
|
||||
MutexArc { x: UnsafeArc::new(data),
|
||||
marker: marker::NoFreeze, }
|
||||
MutexArc { x: UnsafeArc::new(data) }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,17 +294,17 @@ struct RWArcInner<T> { lock: RWLock, failed: bool, data: T }
|
||||
*/
|
||||
pub struct RWArc<T> {
|
||||
priv x: UnsafeArc<RWArcInner<T>>,
|
||||
priv marker: marker::NoFreeze,
|
||||
priv marker1: marker::NoShare,
|
||||
priv marker: marker::NoShare,
|
||||
}
|
||||
|
||||
impl<T: Share + Send> Clone for RWArc<T> {
|
||||
/// Duplicate a rwlock-protected Arc. See arc::clone for more details.
|
||||
#[inline]
|
||||
fn clone(&self) -> RWArc<T> {
|
||||
RWArc { x: self.x.clone(),
|
||||
marker: marker::NoFreeze,
|
||||
marker1: marker::NoShare, }
|
||||
RWArc {
|
||||
x: self.x.clone(),
|
||||
marker: marker::NoShare
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -327,9 +324,10 @@ impl<T: Share + Send> RWArc<T> {
|
||||
lock: RWLock::new_with_condvars(num_condvars),
|
||||
failed: false, data: user_data
|
||||
};
|
||||
RWArc { x: UnsafeArc::new(data),
|
||||
marker: marker::NoFreeze,
|
||||
marker1: marker::NoShare, }
|
||||
RWArc {
|
||||
x: UnsafeArc::new(data),
|
||||
marker: marker::NoShare
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,7 +169,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, Send, and Freeze.
|
||||
// detects Copy, Send and Share.
|
||||
#[deriving(Clone, Eq, Encodable, Decodable, Hash)]
|
||||
pub enum TyParamBound {
|
||||
TraitTyParamBound(TraitRef),
|
||||
|
@ -13,6 +13,6 @@
|
||||
|
||||
#[crate_type="lib"];
|
||||
|
||||
pub trait RequiresFreeze : Freeze { }
|
||||
pub trait RequiresRequiresFreezeAndSend : RequiresFreeze + Send { }
|
||||
pub trait RequiresShare : Share { }
|
||||
pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
|
||||
pub trait RequiresPod : Pod { }
|
||||
|
@ -1,25 +0,0 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that attempt to freeze an `&mut` pointer while referent is
|
||||
// claimed yields an error.
|
||||
//
|
||||
// Example from src/middle/borrowck/doc.rs
|
||||
|
||||
fn foo<'a>(mut t0: &'a mut int,
|
||||
mut t1: &'a mut int) {
|
||||
let p: &mut int = &mut *t0; // Claims `*t0`
|
||||
let mut t2 = &t0; //~ ERROR cannot borrow `t0`
|
||||
let q: &int = &**t2; // Freezes `*t0` but not through `*p`
|
||||
*p += 1; // violates type of `*q`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -16,12 +16,12 @@
|
||||
// Mostly tests correctness of metadata.
|
||||
|
||||
extern crate trait_superkinds_in_metadata;
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
|
||||
|
||||
struct X<T>(T);
|
||||
|
||||
impl <T:Freeze> RequiresFreeze for X<T> { }
|
||||
impl <T:Share> RequiresShare for X<T> { }
|
||||
|
||||
impl <T:Freeze> RequiresRequiresFreezeAndSend for X<T> { } //~ ERROR cannot implement this trait
|
||||
impl <T:Share> RequiresRequiresShareAndSend for X<T> { } //~ ERROR cannot implement this trait
|
||||
|
||||
fn main() { }
|
||||
|
@ -13,10 +13,7 @@
|
||||
|
||||
trait Foo : Send { }
|
||||
|
||||
impl <'a> Foo for &'a mut () { } //~ ERROR cannot implement this trait
|
||||
|
||||
trait Bar : Freeze { }
|
||||
|
||||
impl <'a> Bar for &'a mut () { } //~ ERROR cannot implement this trait
|
||||
impl <'a> Foo for &'a mut () { }
|
||||
//~^ ERROR which does not fulfill `Send`, cannot implement this trait
|
||||
|
||||
fn main() { }
|
||||
|
@ -12,7 +12,7 @@
|
||||
fn take_any(_: ||:) {
|
||||
}
|
||||
|
||||
fn take_const_owned(_: ||:Freeze+Send) {
|
||||
fn take_const_owned(_: ||:Share+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+Freeze` but found bounds `Send`
|
||||
take_const_owned(f); //~ ERROR expected bounds `Send+Share` but found bounds `Send`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,57 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test which of the builtin types are considered freezeable.
|
||||
|
||||
|
||||
fn assert_freeze<T:Freeze>() { }
|
||||
trait Dummy { }
|
||||
|
||||
fn test<'a,T,U:Freeze>(_: &'a int) {
|
||||
// lifetime pointers are ok...
|
||||
assert_freeze::<&'static int>();
|
||||
assert_freeze::<&'a int>();
|
||||
assert_freeze::<&'a str>();
|
||||
assert_freeze::<&'a [int]>();
|
||||
|
||||
// ...unless they are mutable
|
||||
assert_freeze::<&'static mut int>(); //~ ERROR does not fulfill `Freeze`
|
||||
assert_freeze::<&'a mut int>(); //~ ERROR does not fulfill `Freeze`
|
||||
|
||||
// ~ pointers are ok
|
||||
assert_freeze::<~int>();
|
||||
assert_freeze::<~str>();
|
||||
assert_freeze::<Vec<int> >();
|
||||
|
||||
// but not if they own a bad thing
|
||||
assert_freeze::<~&'a mut int>(); //~ ERROR does not fulfill `Freeze`
|
||||
|
||||
// careful with object types, who knows what they close over...
|
||||
assert_freeze::<&'a Dummy>(); //~ ERROR does not fulfill `Freeze`
|
||||
assert_freeze::<~Dummy>(); //~ ERROR does not fulfill `Freeze`
|
||||
|
||||
// ...unless they are properly bounded
|
||||
assert_freeze::<&'a Dummy:Freeze>();
|
||||
assert_freeze::<&'static Dummy:Freeze>();
|
||||
assert_freeze::<~Dummy:Freeze>();
|
||||
|
||||
// ...but even then the pointer overrides
|
||||
assert_freeze::<&'a mut Dummy:Freeze>(); //~ ERROR does not fulfill `Freeze`
|
||||
|
||||
// closures are like an `&mut` object
|
||||
assert_freeze::<||>(); //~ ERROR does not fulfill `Freeze`
|
||||
|
||||
// unsafe ptrs are ok unless they point at unfreezeable things
|
||||
assert_freeze::<*int>();
|
||||
assert_freeze::<*&'a mut int>(); //~ ERROR does not fulfill `Freeze`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
@ -13,11 +13,11 @@
|
||||
|
||||
use std::kinds::marker;
|
||||
|
||||
enum Foo { A(marker::NoFreeze) }
|
||||
enum Foo { A(marker::NoShare) }
|
||||
|
||||
fn bar<T: Freeze>(_: T) {}
|
||||
fn bar<T: Share>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
let x = A(marker::NoFreeze);
|
||||
let x = A(marker::NoShare);
|
||||
bar(&x); //~ ERROR type parameter with an incompatible type
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
fn is_send<T: Send>() {}
|
||||
fn is_freeze<T: Freeze>() {}
|
||||
fn is_freeze<T: Share>() {}
|
||||
fn is_static<T: 'static>() {}
|
||||
|
||||
fn main() {
|
||||
|
@ -14,7 +14,7 @@ trait Foo {
|
||||
fn a(_x: ~Foo:Send) {
|
||||
}
|
||||
|
||||
fn c(x: ~Foo:Freeze+Send) {
|
||||
fn c(x: ~Foo:Share+Send) {
|
||||
a(x);
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,11 @@ fn a(_x: ~Foo) { // should be same as ~Foo:Send
|
||||
fn b(_x: &'static Foo) { // should be same as &'static Foo:'static
|
||||
}
|
||||
|
||||
fn c(x: ~Foo:Freeze) {
|
||||
fn c(x: ~Foo:Share) {
|
||||
a(x); //~ ERROR expected bounds `Send`
|
||||
}
|
||||
|
||||
fn d(x: &'static Foo:Freeze) {
|
||||
fn d(x: &'static Foo:Share) {
|
||||
b(x); //~ ERROR expected bounds `'static`
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,11 @@
|
||||
trait Tr { }
|
||||
impl Tr for int { }
|
||||
|
||||
fn foo(x: ~Tr: Freeze) -> ~Tr: Freeze { x }
|
||||
fn foo(x: ~Tr: Share) -> ~Tr: Share { x }
|
||||
|
||||
fn main() {
|
||||
let x: ~Tr: Freeze;
|
||||
let x: ~Tr: Share;
|
||||
|
||||
~1 as ~Tr: Freeze;
|
||||
~1 as ~Tr: Share;
|
||||
}
|
||||
|
||||
|
@ -16,15 +16,15 @@
|
||||
// even when using them cross-crate.
|
||||
|
||||
extern crate trait_superkinds_in_metadata;
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
|
||||
|
||||
#[deriving(Eq)]
|
||||
struct X<T>(T);
|
||||
|
||||
impl <T: Freeze> RequiresFreeze for X<T> { }
|
||||
impl <T: Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
|
||||
impl <T: Share> RequiresShare for X<T> { }
|
||||
impl <T: Share+Send> RequiresRequiresShareAndSend for X<T> { }
|
||||
|
||||
fn foo<T: RequiresRequiresFreezeAndSend>(val: T, chan: Sender<T>) {
|
||||
fn foo<T: RequiresRequiresShareAndSend>(val: T, chan: Sender<T>) {
|
||||
chan.send(val);
|
||||
}
|
||||
|
||||
|
@ -15,14 +15,14 @@
|
||||
// Tests (correct) usage of trait super-builtin-kinds cross-crate.
|
||||
|
||||
extern crate trait_superkinds_in_metadata;
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresFreezeAndSend, RequiresFreeze};
|
||||
use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
|
||||
use trait_superkinds_in_metadata::{RequiresPod};
|
||||
|
||||
struct X<T>(T);
|
||||
|
||||
impl <T:Freeze> RequiresFreeze for X<T> { }
|
||||
impl <T:Share> RequiresShare for X<T> { }
|
||||
|
||||
impl <T:Freeze+Send> RequiresRequiresFreezeAndSend for X<T> { }
|
||||
impl <T:Share+Send> RequiresRequiresShareAndSend for X<T> { }
|
||||
|
||||
impl <T:Pod> RequiresPod for X<T> { }
|
||||
|
||||
|
@ -12,18 +12,18 @@ fn foo<T>() {}
|
||||
fn bar<T>(_: T) {}
|
||||
|
||||
fn is_send<T: Send>() {}
|
||||
fn is_freeze<T: Freeze>() {}
|
||||
fn is_freeze<T: Share>() {}
|
||||
fn is_static<T: 'static>() {}
|
||||
|
||||
pub fn main() {
|
||||
foo::<proc()>();
|
||||
foo::<proc:()>();
|
||||
foo::<proc:Send()>();
|
||||
foo::<proc:Send + Freeze()>();
|
||||
foo::<proc:'static + Send + Freeze()>();
|
||||
foo::<proc:Send + Share()>();
|
||||
foo::<proc:'static + Send + Share()>();
|
||||
|
||||
is_send::<proc:Send()>();
|
||||
is_freeze::<proc:Freeze()>();
|
||||
is_freeze::<proc:Share()>();
|
||||
is_static::<proc:'static()>();
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ fn a(_x: ~Foo:) {
|
||||
fn b(_x: ~Foo:Send) {
|
||||
}
|
||||
|
||||
fn c(x: ~Foo:Freeze+Send) {
|
||||
fn c(x: ~Foo:Share+Send) {
|
||||
a(x);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
// Tests that a heterogeneous list of existential types can be put inside an Arc
|
||||
// and shared between tasks as long as all types fulfill Freeze+Send.
|
||||
// and shared between tasks as long as all types fulfill Send.
|
||||
|
||||
// ignore-fast
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user