Skip to content

Commit e9b012e

Browse files
committed
---
yaml --- r: 48782 b: refs/heads/snap-stage3 c: e8ddef9 h: refs/heads/master v: v3
1 parent a156dcc commit e9b012e

File tree

203 files changed

+1315
-1070
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

203 files changed

+1315
-1070
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 3bbcac322669cff3abde5be937cc4ec3860f3985
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: dc6901849584da2fe08a52001b7e6bc2c432bfdc
4+
refs/heads/snap-stage3: e8ddef93da5f112795eff66ff7dc7ccccc1baa86
55
refs/heads/try: 2a8fb58d79e685d5ca07b039badcf2ae3ef077ea
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/doc/rust.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ false fn for
214214
if impl
215215
let loop
216216
match mod mut
217-
priv pub
217+
priv pub pure
218218
ref return
219219
self static struct super
220220
true trait type
@@ -936,6 +936,7 @@ Specifically, the following operations are considered unsafe:
936936

937937
- Dereferencing a [raw pointer](#pointer-types).
938938
- Casting a [raw pointer](#pointer-types) to a safe pointer type.
939+
- Breaking the [purity-checking rules](#pure-functions) in a `pure` function.
939940
- Calling an unsafe function.
940941

941942
##### Unsafe blocks
@@ -945,6 +946,42 @@ This facility exists because the static semantics of Rust are a necessary approx
945946
When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe, they can encapsulate that sequence (taken as a whole) within an `unsafe` block. The compiler will consider uses of such code "safe", to the surrounding context.
946947

947948

949+
#### Pure functions
950+
951+
A pure function declaration is identical to a function declaration, except that
952+
it is declared with the additional keyword `pure`. In addition, the typechecker
953+
checks the body of a pure function with a restricted set of typechecking rules.
954+
A pure function may only modify data owned by its own stack frame.
955+
So, a pure function may modify a local variable allocated on the stack, but not a mutable reference that it takes as an argument.
956+
A pure function may only call other pure functions, not general functions.
957+
958+
An example of a pure function:
959+
960+
~~~~
961+
pure fn lt_42(x: int) -> bool {
962+
return (x < 42);
963+
}
964+
~~~~
965+
966+
Pure functions may call other pure functions:
967+
968+
~~~~{.xfail-test}
969+
pure fn pure_length<T>(ls: List<T>) -> uint { ... }
970+
971+
pure fn nonempty_list<T>(ls: List<T>) -> bool { pure_length(ls) > 0u }
972+
~~~~
973+
974+
These purity-checking rules approximate the concept of referential transparency:
975+
that a call-expression could be rewritten with the literal-expression of its return value, without changing the meaning of the program.
976+
Since they are an approximation, sometimes these rules are *too* restrictive.
977+
Rust allows programmers to violate these rules using [`unsafe` blocks](#unsafe-blocks), which we already saw.
978+
As with any `unsafe` block, those that violate static purity carry transfer the burden of safety-proof from the compiler to the programmer.
979+
Programmers should exercise caution when breaking such rules.
980+
981+
For more details on purity, see [the borrowed pointer tutorial][borrow].
982+
983+
[borrow]: tutorial-borrowed-ptr.html
984+
948985
#### Diverging functions
949986

950987
A special kind of function can be declared with a `!` character where the
@@ -1209,10 +1246,10 @@ For example:
12091246

12101247
~~~~
12111248
trait Num {
1212-
static fn from_int(n: int) -> Self;
1249+
static pure fn from_int(n: int) -> Self;
12131250
}
12141251
impl Num for float {
1215-
static fn from_int(n: int) -> float { n as float }
1252+
static pure fn from_int(n: int) -> float { n as float }
12161253
}
12171254
let x: float = Num::from_int(42);
12181255
~~~~
@@ -2606,7 +2643,7 @@ Raw pointers (`*`)
26062643
### Function types
26072644

26082645
The function type-constructor `fn` forms new function types. A function type
2609-
consists of a set of function-type modifiers (`unsafe`, `extern`, etc.),
2646+
consists of a set of function-type modifiers (`pure`, `unsafe`, `extern`, etc.),
26102647
a sequence of input slots and an output slot.
26112648

26122649
An example of a `fn` type:

branches/snap-stage3/doc/tutorial-borrowed-ptr.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,12 @@ For example, we could write a subroutine like this:
486486

487487
~~~
488488
struct Point {x: float, y: float}
489-
fn get_x(p: &'r Point) -> &'r float { &p.x }
489+
fn get_x(p: &r/Point) -> &r/float { &p.x }
490490
~~~
491491

492492
Here, the function `get_x()` returns a pointer into the structure it
493-
was given. The type of the parameter (`&'r Point`) and return type
494-
(`&'r float`) both use a new syntactic form that we have not seen so
493+
was given. The type of the parameter (`&r/Point`) and return type
494+
(`&r/float`) both use a new syntactic form that we have not seen so
495495
far. Here the identifier `r` names the lifetime of the pointer
496496
explicitly. So in effect, this function declares that it takes a
497497
pointer with lifetime `r` and returns a pointer with that same
@@ -572,8 +572,8 @@ function:
572572
# Rectangle(Point, Size) // upper-left, dimensions
573573
# }
574574
# fn compute_area(shape: &Shape) -> float { 0f }
575-
fn select<T>(shape: &'r Shape, threshold: float,
576-
a: &'r T, b: &'r T) -> &'r T {
575+
fn select<T>(shape: &r/Shape, threshold: float,
576+
a: &r/T, b: &r/T) -> &r/T {
577577
if compute_area(shape) > threshold {a} else {b}
578578
}
579579
~~~
@@ -593,17 +593,17 @@ example:
593593
# }
594594
# fn compute_area(shape: &Shape) -> float { 0f }
595595
# fn select<T>(shape: &Shape, threshold: float,
596-
# a: &'r T, b: &'r T) -> &'r T {
596+
# a: &r/T, b: &r/T) -> &r/T {
597597
# if compute_area(shape) > threshold {a} else {b}
598598
# }
599-
// -+ r
600-
fn select_based_on_unit_circle<T>( // |-+ B
601-
threshold: float, a: &'r T, b: &'r T) -> &'r T { // | |
602-
// | |
603-
let shape = Circle(Point {x: 0., y: 0.}, 1.); // | |
604-
select(&shape, threshold, a, b) // | |
605-
} // |-+
606-
// -+
599+
// -+ r
600+
fn select_based_on_unit_circle<T>( // |-+ B
601+
threshold: float, a: &r/T, b: &r/T) -> &r/T { // | |
602+
// | |
603+
let shape = Circle(Point {x: 0., y: 0.}, 1.); // | |
604+
select(&shape, threshold, a, b) // | |
605+
} // |-+
606+
// -+
607607
~~~
608608

609609
In this call to `select()`, the lifetime of the first parameter shape
@@ -629,8 +629,8 @@ returned. Here is how the new `select()` might look:
629629
# Rectangle(Point, Size) // upper-left, dimensions
630630
# }
631631
# fn compute_area(shape: &Shape) -> float { 0f }
632-
fn select<T>(shape: &'tmp Shape, threshold: float,
633-
a: &'r T, b: &'r T) -> &'r T {
632+
fn select<T>(shape: &tmp/Shape, threshold: float,
633+
a: &r/T, b: &r/T) -> &r/T {
634634
if compute_area(shape) > threshold {a} else {b}
635635
}
636636
~~~
@@ -649,7 +649,7 @@ concise to just omit the named lifetime for `shape` altogether:
649649
# }
650650
# fn compute_area(shape: &Shape) -> float { 0f }
651651
fn select<T>(shape: &Shape, threshold: float,
652-
a: &'r T, b: &'r T) -> &'r T {
652+
a: &r/T, b: &r/T) -> &r/T {
653653
if compute_area(shape) > threshold {a} else {b}
654654
}
655655
~~~

branches/snap-stage3/src/libcore/at_vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ pub mod traits {
174174
use kinds::Copy;
175175
use ops::Add;
176176

177-
impl<T:Copy> Add<&'self [const T],@[T]> for @[T] {
177+
impl<T:Copy> Add<&self/[const T],@[T]> for @[T] {
178178
#[inline(always)]
179-
pure fn add(&self, rhs: & &'self [const T]) -> @[T] {
179+
pure fn add(&self, rhs: & &self/[const T]) -> @[T] {
180180
append(*self, (*rhs))
181181
}
182182
}

branches/snap-stage3/src/libcore/cast.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ pub unsafe fn transmute<L, G>(thing: L) -> G {
5959

6060
/// Coerce an immutable reference to be mutable.
6161
#[inline(always)]
62-
pub unsafe fn transmute_mut<T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }
62+
pub unsafe fn transmute_mut<T>(ptr: &a/T) -> &a/mut T { transmute(ptr) }
6363

6464
/// Coerce a mutable reference to be immutable.
6565
#[inline(always)]
66-
pub unsafe fn transmute_immut<T>(ptr: &'a mut T) -> &'a T {
66+
pub unsafe fn transmute_immut<T>(ptr: &a/mut T) -> &a/T {
6767
transmute(ptr)
6868
}
6969

7070
/// Coerce a borrowed pointer to have an arbitrary associated region.
7171
#[inline(always)]
72-
pub unsafe fn transmute_region<T>(ptr: &'a T) -> &'b T { transmute(ptr) }
72+
pub unsafe fn transmute_region<T>(ptr: &a/T) -> &b/T { transmute(ptr) }
7373

7474
/// Coerce an immutable reference to be mutable.
7575
#[inline(always)]
@@ -85,19 +85,19 @@ pub unsafe fn transmute_immut_unsafe<T>(ptr: *const T) -> *T {
8585

8686
/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
8787
#[inline(always)]
88-
pub unsafe fn transmute_mut_region<T>(ptr: &'a mut T) -> &'b mut T {
88+
pub unsafe fn transmute_mut_region<T>(ptr: &a/mut T) -> &b/mut T {
8989
transmute(ptr)
9090
}
9191

9292
/// Transforms lifetime of the second pointer to match the first.
9393
#[inline(always)]
94-
pub unsafe fn copy_lifetime<S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
94+
pub unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
9595
transmute_region(ptr)
9696
}
9797

9898
/// Transforms lifetime of the second pointer to match the first.
9999
#[inline(always)]
100-
pub unsafe fn copy_lifetime_vec<S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
100+
pub unsafe fn copy_lifetime_vec<S,T>(_ptr: &a/[S], ptr: &T) -> &a/T {
101101
transmute_region(ptr)
102102
}
103103

branches/snap-stage3/src/libcore/cell.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,18 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use cast::transmute;
1211
use option;
1312
use prelude::*;
1413

1514
/// A dynamic, mutable location.
1615
///
1716
/// Similar to a mutable option type, but friendlier.
1817
18+
#[deriving_eq]
1919
pub struct Cell<T> {
2020
mut value: Option<T>
2121
}
2222

23-
impl<T:cmp::Eq> cmp::Eq for Cell<T> {
24-
pure fn eq(&self, other: &Cell<T>) -> bool {
25-
unsafe {
26-
let frozen_self: &Option<T> = transmute(&mut self.value);
27-
let frozen_other: &Option<T> = transmute(&mut other.value);
28-
frozen_self == frozen_other
29-
}
30-
}
31-
pure fn ne(&self, other: &Cell<T>) -> bool { !self.eq(other) }
32-
}
33-
3423
/// Creates a new full cell with the given value.
3524
pub fn Cell<T>(value: T) -> Cell<T> {
3625
Cell { value: Some(value) }

branches/snap-stage3/src/libcore/cleanup.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use cast::transmute;
2222
* NB: These must match the representation in the C++ runtime.
2323
*/
2424

25-
type DropGlue = &'self fn(**TypeDesc, *c_void);
26-
type FreeGlue = &'self fn(**TypeDesc, *c_void);
25+
type DropGlue = &self/fn(**TypeDesc, *c_void);
26+
type FreeGlue = &self/fn(**TypeDesc, *c_void);
2727

2828
type TaskID = uintptr_t;
2929

branches/snap-stage3/src/libcore/comm.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use cast;
1211
use either::{Either, Left, Right};
1312
use kinds::Owned;
1413
use option;
1514
use option::{Option, Some, None, unwrap};
16-
use uint;
1715
use unstable;
1816
use vec;
1917

@@ -285,12 +283,8 @@ impl<T: Owned> Peekable<T> for PortSet<T> {
285283
pure fn port_set_peek<T:Owned>(self: &PortSet<T>) -> bool {
286284
// It'd be nice to use self.port.each, but that version isn't
287285
// pure.
288-
for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
289-
// XXX: Botch pending demuting.
290-
unsafe {
291-
let port: &Port<T> = cast::transmute(&mut self.ports[i]);
292-
if port.peek() { return true }
293-
}
286+
for vec::each(self.ports) |p| {
287+
if p.peek() { return true }
294288
}
295289
false
296290
}

branches/snap-stage3/src/libcore/condition.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ pub struct Handler<T, U> {
2121
}
2222

2323
pub struct Condition<T, U> {
24-
name: &'static str,
24+
name: &static/str,
2525
key: task::local_data::LocalDataKey/&self<Handler<T, U>>
2626
}
2727

2828
pub impl<T, U> Condition/&self<T, U> {
29-
fn trap(&self, h: &'self fn(T) -> U) -> Trap/&self<T, U> {
29+
fn trap(&self, h: &self/fn(T) -> U) -> Trap/&self<T, U> {
3030
unsafe {
3131
let p : *RustClosure = ::cast::transmute(&h);
3232
let prev = task::local_data::local_data_get(self.key);
@@ -65,12 +65,12 @@ pub impl<T, U> Condition/&self<T, U> {
6565
}
6666

6767
struct Trap<T, U> {
68-
cond: &'self Condition/&self<T, U>,
68+
cond: &self/Condition/&self<T, U>,
6969
handler: @Handler<T, U>
7070
}
7171

7272
pub impl<T, U> Trap/&self<T, U> {
73-
fn in<V>(&self, inner: &'self fn() -> V) -> V {
73+
fn in<V>(&self, inner: &self/fn() -> V) -> V {
7474
unsafe {
7575
let _g = Guard { cond: self.cond };
7676
debug!("Trap: pushing handler to TLS");
@@ -81,7 +81,7 @@ pub impl<T, U> Trap/&self<T, U> {
8181
}
8282

8383
struct Guard<T, U> {
84-
cond: &'self Condition/&self<T, U>
84+
cond: &self/Condition/&self<T, U>
8585
}
8686

8787
impl<T, U> Drop for Guard/&self<T, U> {

branches/snap-stage3/src/libcore/container.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ use option::Option;
1414

1515
pub trait Container {
1616
/// Return the number of elements in the container
17-
pure fn len(&const self) -> uint;
17+
pure fn len(&self) -> uint;
1818

1919
/// Return true if the container contains no elements
20-
pure fn is_empty(&const self) -> bool;
20+
pure fn is_empty(&self) -> bool;
2121
}
2222

2323
pub trait Mutable: Container {
@@ -39,7 +39,7 @@ pub trait Map<K, V>: Mutable {
3939
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool);
4040

4141
/// Return the value corresponding to the key in the map
42-
pure fn find(&self, key: &K) -> Option<&'self V>;
42+
pure fn find(&self, key: &K) -> Option<&self/V>;
4343

4444
/// Insert a key-value pair into the map. An existing value for a
4545
/// key is replaced by the new value. Return true if the key did

branches/snap-stage3/src/libcore/gc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
122122
return None;
123123
}
124124

125-
type Visitor = &'self fn(root: **Word, tydesc: *Word) -> bool;
125+
type Visitor = &self/fn(root: **Word, tydesc: *Word) -> bool;
126126

127127
// Walks the list of roots for the given safe point, and calls visitor
128128
// on each root.

0 commit comments

Comments
 (0)