Skip to content

Commit a125540

Browse files
committed
---
yaml --- r: 150194 b: refs/heads/try2 c: a73d2c7 h: refs/heads/master v: v3
1 parent a564495 commit a125540

37 files changed

+232
-202
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 7e7a5e3d3eabe0ee46474b0eb701c159a45b490f
8+
refs/heads/try2: a73d2c70d4c24b85f3846d79b241ba1eb5f95e23
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/doc/guide-tasks.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,14 @@ Here is the function that implements the child task:
493493
~~~
494494
extern crate sync;
495495
# fn main() {
496-
fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
497-
let mut value: uint;
498-
loop {
499-
value = channel.recv();
500-
channel.send(value.to_str());
501-
if value == 0 { break; }
502-
}
496+
fn stringifier(channel: &sync::DuplexStream<~str, uint>) {
497+
let mut value: uint;
498+
loop {
499+
value = channel.recv();
500+
channel.send(value.to_str());
501+
if value == 0 { break; }
503502
}
503+
}
504504
# }
505505
~~~~
506506

branches/try2/src/doc/rust.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ never invoking this behaviour or exposing an API making it possible for it to oc
10191019

10201020
* Data races
10211021
* Dereferencing a null/dangling raw pointer
1022-
* Mutating an immutable value/reference
1022+
* Mutating an immutable value/reference, if it is not marked as non-`Freeze`
10231023
* Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values) (uninitialized) memory
10241024
* Breaking the [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
10251025
with raw pointers (a subset of the rules used by C)
@@ -3434,6 +3434,10 @@ call to the method `make_string`.
34343434
Types in Rust are categorized into kinds, based on various properties of the components of the type.
34353435
The kinds are:
34363436

3437+
`Freeze`
3438+
: Types of this kind are deeply immutable;
3439+
they contain no mutable memory locations
3440+
directly or indirectly via pointers.
34373441
`Send`
34383442
: Types of this kind can be safely sent between tasks.
34393443
This kind includes scalars, owning pointers, owned closures, and

branches/try2/src/doc/tutorial.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,10 @@ unless they contain managed boxes, managed closures, or references.
20992099
These are types that are safe to be used across several threads with access to
21002100
a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal mutable data.
21012101
2102+
* `Freeze` - Constant (immutable) types.
2103+
These are types that do not contain anything intrinsically mutable.
2104+
Intrinsically mutable values include `Cell` in the standard library.
2105+
21022106
* `'static` - Non-borrowed types.
21032107
These are types that do not contain any data whose lifetime is bound to
21042108
a particular stack frame. These are types that do not contain any
@@ -2148,7 +2152,7 @@ We say that the `Printable` trait _provides_ a `print` method with the
21482152
given signature. This means that we can call `print` on an argument
21492153
of any type that implements the `Printable` trait.
21502154
2151-
Rust's built-in `Send` and `Share` types are examples of traits that
2155+
Rust's built-in `Send` and `Freeze` types are examples of traits that
21522156
don't provide any methods.
21532157
21542158
Traits may be implemented for specific types with [impls]. An impl for
@@ -2440,15 +2444,15 @@ Consequently, the trait objects themselves automatically fulfill their
24402444
respective kind bounds. However, this default behavior can be overridden by
24412445
specifying a list of bounds on the trait type, for example, by writing `~Trait:`
24422446
(which indicates that the contents of the owned trait need not fulfill any
2443-
bounds), or by writing `~Trait:Send+Share`, which indicates that in addition
2444-
to fulfilling `Send`, contents must also fulfill `Share`, and as a consequence,
2445-
the trait itself fulfills `Share`.
2447+
bounds), or by writing `~Trait:Send+Freeze`, which indicates that in addition
2448+
to fulfilling `Send`, contents must also fulfill `Freeze`, and as a consequence,
2449+
the trait itself fulfills `Freeze`.
24462450
24472451
* `~Trait:Send` is equivalent to `~Trait`.
24482452
* `&Trait:` is equivalent to `&Trait`.
24492453
24502454
Builtin kind bounds can also be specified on closure types in the same way (for
2451-
example, by writing `fn:Send()`), and the default behaviours are the same as
2455+
example, by writing `fn:Freeze()`), and the default behaviours are the same as
24522456
for traits of the same storage class.
24532457
24542458
## Trait inheritance

branches/try2/src/libarena/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use std::mem;
3737
use std::ptr::read;
3838
use std::cmp;
3939
use std::num;
40+
use std::kinds::marker;
4041
use std::rc::Rc;
4142
use std::rt::global_heap;
4243
use std::intrinsics::{TyDesc, get_tydesc};
@@ -89,6 +90,7 @@ pub struct Arena {
8990
priv head: Chunk,
9091
priv pod_head: Chunk,
9192
priv chunks: RefCell<@List<Chunk>>,
93+
priv no_freeze: marker::NoFreeze,
9294
}
9395

9496
impl Arena {
@@ -101,6 +103,7 @@ impl Arena {
101103
head: chunk(initial_size, false),
102104
pod_head: chunk(initial_size, true),
103105
chunks: RefCell::new(@Nil),
106+
no_freeze: marker::NoFreeze,
104107
}
105108
}
106109
}

branches/try2/src/librustc/metadata/tydecode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,9 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
584584
'S' => {
585585
param_bounds.builtin_bounds.add(ty::BoundSend);
586586
}
587+
'K' => {
588+
param_bounds.builtin_bounds.add(ty::BoundFreeze);
589+
}
587590
'O' => {
588591
param_bounds.builtin_bounds.add(ty::BoundStatic);
589592
}

branches/try2/src/librustc/metadata/tyencode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
392392
for bound in bs.builtin_bounds.iter() {
393393
match bound {
394394
ty::BoundSend => mywrite!(w, "S"),
395+
ty::BoundFreeze => mywrite!(w, "K"),
395396
ty::BoundStatic => mywrite!(w, "O"),
396397
ty::BoundSized => mywrite!(w, "Z"),
397398
ty::BoundPod => mywrite!(w, "P"),

branches/try2/src/librustc/middle/kind.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,20 @@ use syntax::visit::Visitor;
3030
// kind is noncopyable. The noncopyable kind can be extended with any number
3131
// of the following attributes.
3232
//
33-
// Send: Things that can be sent on channels or included in spawned closures. It
34-
// includes scalar types as well as classes and unique types containing only
35-
// sendable types.
33+
// send: Things that can be sent on channels or included in spawned closures.
34+
// freeze: Things thare are deeply immutable. They are guaranteed never to
35+
// change, and can be safely shared without copying between tasks.
3636
// 'static: Things that do not contain references.
3737
//
38+
// Send includes scalar types as well as classes and unique types containing
39+
// only sendable types.
40+
//
41+
// Freeze include scalar types, things without non-const fields, and pointers
42+
// to freezable things.
43+
//
3844
// This pass ensures that type parameters are only instantiated with types
3945
// whose kinds are equal or less general than the way the type parameter was
40-
// annotated (with the `Send` bound).
46+
// annotated (with the `Send` or `Freeze` bound).
4147
//
4248
// It also verifies that noncopyable kinds are not copied. Sendability is not
4349
// applied, since none of our language primitives send. Instead, the sending

branches/try2/src/librustc/middle/lang_items.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// Language items are items that represent concepts intrinsic to the language
1414
// itself. Examples are:
1515
//
16-
// * Traits that specify "kinds"; e.g. "Share", "Send".
16+
// * Traits that specify "kinds"; e.g. "Freeze", "Send".
1717
//
1818
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
1919
//
@@ -82,7 +82,9 @@ impl LanguageItems {
8282
}
8383

8484
pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
85-
if Some(id) == self.send_trait() {
85+
if Some(id) == self.freeze_trait() {
86+
Some(ty::BoundFreeze)
87+
} else if Some(id) == self.send_trait() {
8688
Some(ty::BoundSend)
8789
} else if Some(id) == self.sized_trait() {
8890
Some(ty::BoundSized)
@@ -208,6 +210,7 @@ pub fn collect_language_items(krate: &ast::Crate,
208210

209211
lets_do_this! {
210212
// Variant name, Name, Method name;
213+
FreezeTraitLangItem, "freeze", freeze_trait;
211214
SendTraitLangItem, "send", send_trait;
212215
SizedTraitLangItem, "sized", sized_trait;
213216
PodTraitLangItem, "pod", pod_trait;
@@ -272,6 +275,7 @@ lets_do_this! {
272275
ContravariantLifetimeItem, "contravariant_lifetime", contravariant_lifetime;
273276
InvariantLifetimeItem, "invariant_lifetime", invariant_lifetime;
274277

278+
NoFreezeItem, "no_freeze_bound", no_freeze_bound;
275279
NoSendItem, "no_send_bound", no_send_bound;
276280
NoPodItem, "no_pod_bound", no_pod_bound;
277281
NoShareItem, "no_share_bound", no_share_bound;

branches/try2/src/librustc/middle/ty.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ pub type BuiltinBounds = EnumSet<BuiltinBound>;
838838
pub enum BuiltinBound {
839839
BoundStatic,
840840
BoundSend,
841+
BoundFreeze,
841842
BoundSized,
842843
BoundPod,
843844
BoundShare,
@@ -851,6 +852,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
851852
let mut set = EnumSet::empty();
852853
set.add(BoundStatic);
853854
set.add(BoundSend);
855+
set.add(BoundFreeze);
854856
set.add(BoundSized);
855857
set.add(BoundShare);
856858
set
@@ -1890,6 +1892,9 @@ def_type_content_sets!(
18901892
// that it neither reaches nor owns a managed pointer.
18911893
Nonsendable = 0b0000_0111__0000_0100__0000,
18921894

1895+
// Things that prevent values from being considered freezable
1896+
Nonfreezable = 0b0000_1000__0000_0000__0000,
1897+
18931898
// Things that prevent values from being considered 'static
18941899
Nonstatic = 0b0000_0010__0000_0000__0000,
18951900

@@ -1924,6 +1929,7 @@ impl TypeContents {
19241929
pub fn meets_bound(&self, cx: &ctxt, bb: BuiltinBound) -> bool {
19251930
match bb {
19261931
BoundStatic => self.is_static(cx),
1932+
BoundFreeze => self.is_freezable(cx),
19271933
BoundSend => self.is_sendable(cx),
19281934
BoundSized => self.is_sized(cx),
19291935
BoundPod => self.is_pod(cx),
@@ -1959,6 +1965,10 @@ impl TypeContents {
19591965
self.intersects(TC::OwnsOwned)
19601966
}
19611967

1968+
pub fn is_freezable(&self, _: &ctxt) -> bool {
1969+
!self.intersects(TC::Nonfreezable)
1970+
}
1971+
19621972
pub fn is_sized(&self, _: &ctxt) -> bool {
19631973
!self.intersects(TC::Nonsized)
19641974
}
@@ -2063,6 +2073,10 @@ pub fn type_is_sendable(cx: &ctxt, t: ty::t) -> bool {
20632073
type_contents(cx, t).is_sendable(cx)
20642074
}
20652075

2076+
pub fn type_is_freezable(cx: &ctxt, t: ty::t) -> bool {
2077+
type_contents(cx, t).is_freezable(cx)
2078+
}
2079+
20662080
pub fn type_interior_is_unsafe(cx: &ctxt, t: ty::t) -> bool {
20672081
type_contents(cx, t).interior_unsafe()
20682082
}
@@ -2118,7 +2132,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
21182132
cache.insert(ty_id, TC::None);
21192133

21202134
let result = match get(ty).sty {
2121-
// Scalar and unique types are sendable, and durable
2135+
// Scalar and unique types are sendable, freezable, and durable
21222136
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
21232137
ty_bare_fn(_) | ty::ty_char => {
21242138
TC::None
@@ -2256,7 +2270,9 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
22562270
did: ast::DefId,
22572271
tc: TypeContents)
22582272
-> TypeContents {
2259-
if Some(did) == cx.lang_items.no_send_bound() {
2273+
if Some(did) == cx.lang_items.no_freeze_bound() {
2274+
tc | TC::ReachesMutable
2275+
} else if Some(did) == cx.lang_items.no_send_bound() {
22602276
tc | TC::ReachesNonsendAnnot
22612277
} else if Some(did) == cx.lang_items.managed_bound() {
22622278
tc | TC::Managed
@@ -2341,6 +2357,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
23412357
tc = tc - match bound {
23422358
BoundStatic => TC::Nonstatic,
23432359
BoundSend => TC::Nonsendable,
2360+
BoundFreeze => TC::Nonfreezable,
23442361
BoundSized => TC::Nonsized,
23452362
BoundPod => TC::Nonpod,
23462363
BoundShare => TC::Nonsharable,

branches/try2/src/librustc/middle/typeck/collect.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,8 @@ pub fn ty_generics(ccx: &CrateCtxt,
976976
* Translate the AST's notion of ty param bounds (which are an
977977
* enum consisting of a newtyped Ty or a region) to ty's
978978
* notion of ty param bounds, which can either be user-defined
979-
* traits, or the built-in trait (formerly known as kind): Send.
979+
* traits, or one of the two built-in traits (formerly known
980+
* as kinds): Freeze and Send.
980981
*/
981982

982983
let mut param_bounds = ty::ParamBounds {

branches/try2/src/librustc/util/ppaux.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ impl Repr for ty::ParamBounds {
664664
res.push(match b {
665665
ty::BoundStatic => ~"'static",
666666
ty::BoundSend => ~"Send",
667+
ty::BoundFreeze => ~"Freeze",
667668
ty::BoundSized => ~"Sized",
668669
ty::BoundPod => ~"Pod",
669670
ty::BoundShare => ~"Share",
@@ -951,6 +952,7 @@ impl UserString for ty::BuiltinBound {
951952
match *self {
952953
ty::BoundStatic => ~"'static",
953954
ty::BoundSend => ~"Send",
955+
ty::BoundFreeze => ~"Freeze",
954956
ty::BoundSized => ~"Sized",
955957
ty::BoundPod => ~"Pod",
956958
ty::BoundShare => ~"Share",

branches/try2/src/librustdoc/html/render.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ pub enum Implementor {
116116
///
117117
/// This structure purposefully does not implement `Clone` because it's intended
118118
/// to be a fairly large and expensive structure to clone. Instead this adheres
119-
/// to `Send` so it may be stored in a `Arc` instance and shared among the various
120-
/// rendering tasks.
119+
/// to both `Send` and `Freeze` so it may be stored in a `Arc` instance and
120+
/// shared among the various rendering tasks.
121121
pub struct Cache {
122122
/// Mapping of typaram ids to the name of the type parameter. This is used
123123
/// when pretty-printing a type (so pretty printing doesn't have to

branches/try2/src/libstd/cell.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ use ty::Unsafe;
2222
/// A mutable memory location that admits only `Pod` data.
2323
pub struct Cell<T> {
2424
priv value: Unsafe<T>,
25-
priv noshare: marker::NoShare,
25+
priv marker1: marker::NoFreeze,
26+
priv marker2: marker::NoShare,
2627
}
2728

2829
impl<T:Pod> Cell<T> {
2930
/// Creates a new `Cell` containing the given value.
3031
pub fn new(value: T) -> Cell<T> {
3132
Cell {
3233
value: Unsafe::new(value),
33-
noshare: marker::NoShare,
34+
marker1: marker::NoFreeze,
35+
marker2: marker::NoShare,
3436
}
3537
}
3638

@@ -71,8 +73,9 @@ impl<T: fmt::Show> fmt::Show for Cell<T> {
7173
pub struct RefCell<T> {
7274
priv value: Unsafe<T>,
7375
priv borrow: BorrowFlag,
74-
priv nopod: marker::NoPod,
75-
priv noshare: marker::NoShare,
76+
priv marker1: marker::NoFreeze,
77+
priv marker2: marker::NoPod,
78+
priv marker3: marker::NoShare,
7679
}
7780

7881
// Values [1, MAX-1] represent the number of `Ref` active
@@ -85,9 +88,10 @@ impl<T> RefCell<T> {
8588
/// Create a new `RefCell` containing `value`
8689
pub fn new(value: T) -> RefCell<T> {
8790
RefCell {
91+
marker1: marker::NoFreeze,
92+
marker2: marker::NoPod,
93+
marker3: marker::NoShare,
8894
value: Unsafe::new(value),
89-
nopod: marker::NoPod,
90-
noshare: marker::NoShare,
9195
borrow: UNUSED,
9296
}
9397
}

branches/try2/src/libstd/comm/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pub struct Receiver<T> {
291291
priv inner: Flavor<T>,
292292
priv receives: Cell<uint>,
293293
// can't share in an arc
294-
priv marker: marker::NoShare,
294+
priv marker: marker::NoFreeze,
295295
}
296296

297297
/// An iterator over messages on a receiver, this iterator will block
@@ -307,7 +307,7 @@ pub struct Sender<T> {
307307
priv inner: Flavor<T>,
308308
priv sends: Cell<uint>,
309309
// can't share in an arc
310-
priv marker: marker::NoShare,
310+
priv marker: marker::NoFreeze,
311311
}
312312

313313
/// 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>) {
340340

341341
impl<T: Send> Sender<T> {
342342
fn my_new(inner: Flavor<T>) -> Sender<T> {
343-
Sender { inner: inner, sends: Cell::new(0), marker: marker::NoShare }
343+
Sender { inner: inner, sends: Cell::new(0), marker: marker::NoFreeze }
344344
}
345345

346346
/// Sends a value along this channel to be received by the corresponding
@@ -478,7 +478,7 @@ impl<T: Send> Drop for Sender<T> {
478478

479479
impl<T: Send> Receiver<T> {
480480
fn my_new(inner: Flavor<T>) -> Receiver<T> {
481-
Receiver { inner: inner, receives: Cell::new(0), marker: marker::NoShare }
481+
Receiver { inner: inner, receives: Cell::new(0), marker: marker::NoFreeze }
482482
}
483483

484484
/// Blocks waiting for a value on this receiver

0 commit comments

Comments
 (0)