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:
bors 2014-03-22 13:01:52 -07:00
commit 7e7a5e3d3e
34 changed files with 72 additions and 224 deletions

View File

@ -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

View File

@ -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

View File

@ -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,
}
}
}

View File

@ -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);
}

View File

@ -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"),

View File

@ -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

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. "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;

View File

@ -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,

View File

@ -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 {

View File

@ -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",

View File

@ -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

View File

@ -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,
}
}

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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};

View File

@ -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
}
}
/**

View File

@ -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),

View File

@ -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 { }

View File

@ -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() {
}

View File

@ -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() { }

View File

@ -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() { }

View File

@ -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() {}

View File

@ -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() {
}

View File

@ -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
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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`
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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> { }

View File

@ -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()>();

View File

@ -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);
}

View File

@ -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