Skip to content

Commit

Permalink
auto merge of #13076 : FlaPer87/rust/remove-freeze, r=alexcrichton
Browse files Browse the repository at this point in the history
This PR removes the `Freeze` kind and the `NoFreeze` marker completely.

Fixes #12577

cc @nikomatsakis r?
  • Loading branch information
bors committed Mar 22, 2014
2 parents 0e6f90e + a1cb2f5 commit 7e7a5e3
Show file tree
Hide file tree
Showing 34 changed files with 72 additions and 224 deletions.
6 changes: 1 addition & 5 deletions src/doc/rust.md
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
14 changes: 5 additions & 9 deletions src/doc/tutorial.md
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/libarena/lib.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/metadata/tydecode.rs
Expand Up @@ -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);
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc/metadata/tyencode.rs
Expand Up @@ -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"),
Expand Down
14 changes: 4 additions & 10 deletions src/librustc/middle/kind.rs
Expand Up @@ -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
Expand Down
8 changes: 2 additions & 6 deletions src/librustc/middle/lang_items.rs
Expand Up @@ -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".
//
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
21 changes: 2 additions & 19 deletions src/librustc/middle/ty.rs
Expand Up @@ -838,7 +838,6 @@ pub type BuiltinBounds = EnumSet<BuiltinBound>;
pub enum BuiltinBound {
BoundStatic,
BoundSend,
BoundFreeze,
BoundSized,
BoundPod,
BoundShare,
Expand All @@ -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
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/typeck/collect.rs
Expand Up @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/util/ppaux.rs
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/render.rs
Expand Up @@ -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
Expand Down
16 changes: 6 additions & 10 deletions src/libstd/cell.rs
Expand Up @@ -22,17 +22,15 @@ 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> {
/// Creates a new `Cell` containing the given value.
pub fn new(value: T) -> Cell<T> {
Cell {
value: Unsafe::new(value),
marker1: marker::NoFreeze,
marker2: marker::NoShare,
noshare: marker::NoShare,
}
}

Expand Down Expand Up @@ -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
Expand All @@ -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,
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/libstd/comm/mod.rs
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 0 additions & 2 deletions src/libstd/comm/select.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit 7e7a5e3

Please sign in to comment.