Skip to content

Commit 7a2265d

Browse files
committed
---
yaml --- r: 139062 b: refs/heads/try2 c: 299995c h: refs/heads/master v: v3
1 parent e056028 commit 7a2265d

Some content is hidden

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

81 files changed

+687
-628
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: e78f2e2ac577f9c47cd58af52d3bcd496254545d
8+
refs/heads/try2: 299995c2b62c520708d450e4b7c6d360be0fd852
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/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/try2/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
~~~
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
"Highlight the 100th text column
1+
"Highlight the 78th text column
22
"Feature became available in v7.3
33
if version >= 703
4-
set colorcolumn=100
4+
set colorcolumn=78
55
endif

branches/try2/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/try2/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/try2/src/libcore/container.rs

Lines changed: 2 additions & 2 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 {

branches/try2/src/libcore/hashmap.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,10 @@ pub mod linear {
290290
291291
impl<K:Hash + IterBytes + Eq,V> Container for LinearMap<K, V> {
292292
/// Return the number of elements in the map
293-
pure fn len(&const self) -> uint { self.size }
293+
pure fn len(&self) -> uint { self.size }
294294
295295
/// Return true if the map contains no elements
296-
pure fn is_empty(&const self) -> bool { self.len() == 0 }
296+
pure fn is_empty(&self) -> bool { self.len() == 0 }
297297
}
298298
299299
impl<K:Hash + IterBytes + Eq,V> Mutable for LinearMap<K, V> {
@@ -555,10 +555,10 @@ pub mod linear {
555555

556556
impl<T:Hash + IterBytes + Eq> Container for LinearSet<T> {
557557
/// Return the number of elements in the set
558-
pure fn len(&const self) -> uint { self.map.len() }
558+
pure fn len(&self) -> uint { self.map.len() }
559559

560560
/// Return true if the set contains no elements
561-
pure fn is_empty(&const self) -> bool { self.map.is_empty() }
561+
pure fn is_empty(&self) -> bool { self.map.is_empty() }
562562
}
563563

564564
impl<T:Hash + IterBytes + Eq> Mutable for LinearSet<T> {

branches/try2/src/libcore/io.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ pub struct BytesReader {
593593
mut pos: uint
594594
}
595595
596-
impl Reader for BytesReader<'self> {
596+
impl Reader for BytesReader/&self {
597597
fn read(&self, bytes: &mut [u8], len: uint) -> uint {
598598
let count = uint::min(len, self.bytes.len() - self.pos);
599599
@@ -1116,7 +1116,7 @@ pub struct BytesWriter {
11161116
impl Writer for BytesWriter {
11171117
fn write(&self, v: &[const u8]) {
11181118
let v_len = v.len();
1119-
let bytes_len = vec::uniq_len(&const self.bytes);
1119+
let bytes_len = self.bytes.len();
11201120
11211121
let count = uint::max(bytes_len, self.pos + v_len);
11221122
vec::reserve(&mut self.bytes, count);
@@ -1131,7 +1131,7 @@ impl Writer for BytesWriter {
11311131
}
11321132
fn seek(&self, offset: int, whence: SeekStyle) {
11331133
let pos = self.pos;
1134-
let len = vec::uniq_len(&const self.bytes);
1134+
let len = self.bytes.len();
11351135
self.pos = seek_in_buf(offset, pos, len, whence);
11361136
}
11371137
fn tell(&self) -> uint { self.pos }

branches/try2/src/libcore/mutable.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ pub fn unwrap<T>(m: Mut<T>) -> T {
4646
pub impl<T> Data<T> {
4747
fn borrow_mut<R>(&self, op: &fn(t: &mut T) -> R) -> R {
4848
match self.mode {
49-
Immutable => fail!(~"currently immutable"),
49+
Immutable => fail!(fmt!("%? currently immutable",
50+
self.value)),
5051
ReadOnly | Mutable => {}
5152
}
5253

@@ -61,7 +62,8 @@ pub impl<T> Data<T> {
6162

6263
fn borrow_imm<R>(&self, op: &fn(t: &T) -> R) -> R {
6364
match self.mode {
64-
Mutable => fail!(~"currently mutable"),
65+
Mutable => fail!(fmt!("%? currently mutable",
66+
self.value)),
6567
ReadOnly | Immutable => {}
6668
}
6769

branches/try2/src/libcore/option.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,14 @@ pub pure fn while_some<T>(x: Option<T>, blk: &fn(v: T) -> Option<T>) {
228228
}
229229
230230
#[inline(always)]
231-
pub pure fn is_none<T>(opt: &const Option<T>) -> bool {
231+
pub pure fn is_none<T>(opt: &Option<T>) -> bool {
232232
//! Returns true if the option equals `none`
233233
234234
match *opt { None => true, Some(_) => false }
235235
}
236236
237237
#[inline(always)]
238-
pub pure fn is_some<T>(opt: &const Option<T>) -> bool {
238+
pub pure fn is_some<T>(opt: &Option<T>) -> bool {
239239
//! Returns true if the option contains some value
240240
241241
!is_none(opt)
@@ -333,11 +333,11 @@ impl<T> MutableIter<T> for Option<T> {
333333
pub impl<T> Option<T> {
334334
/// Returns true if the option equals `none`
335335
#[inline(always)]
336-
pure fn is_none(&const self) -> bool { is_none(self) }
336+
pure fn is_none(&self) -> bool { is_none(self) }
337337
338338
/// Returns true if the option contains some value
339339
#[inline(always)]
340-
pure fn is_some(&const self) -> bool { is_some(self) }
340+
pure fn is_some(&self) -> bool { is_some(self) }
341341
342342
/**
343343
* Update an optional value by optionally running its content by reference

branches/try2/src/libcore/ptr.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,20 +223,20 @@ pub unsafe fn array_each<T>(arr: **T, cb: &fn(*T)) {
223223
}
224224
225225
pub trait Ptr<T> {
226-
pure fn is_null(&const self) -> bool;
227-
pure fn is_not_null(&const self) -> bool;
226+
pure fn is_null(&self) -> bool;
227+
pure fn is_not_null(&self) -> bool;
228228
pure fn offset(&self, count: uint) -> Self;
229229
}
230230
231231
/// Extension methods for immutable pointers
232232
impl<T> Ptr<T> for *T {
233233
/// Returns true if the pointer is equal to the null pointer.
234234
#[inline(always)]
235-
pure fn is_null(&const self) -> bool { is_null(*self) }
235+
pure fn is_null(&self) -> bool { is_null(*self) }
236236
237237
/// Returns true if the pointer is not equal to the null pointer.
238238
#[inline(always)]
239-
pure fn is_not_null(&const self) -> bool { is_not_null(*self) }
239+
pure fn is_not_null(&self) -> bool { is_not_null(*self) }
240240
241241
/// Calculates the offset from a pointer.
242242
#[inline(always)]
@@ -247,11 +247,11 @@ impl<T> Ptr<T> for *T {
247247
impl<T> Ptr<T> for *mut T {
248248
/// Returns true if the pointer is equal to the null pointer.
249249
#[inline(always)]
250-
pure fn is_null(&const self) -> bool { is_null(*self) }
250+
pure fn is_null(&self) -> bool { is_null(*self) }
251251
252252
/// Returns true if the pointer is not equal to the null pointer.
253253
#[inline(always)]
254-
pure fn is_not_null(&const self) -> bool { is_not_null(*self) }
254+
pure fn is_not_null(&self) -> bool { is_not_null(*self) }
255255
256256
/// Calculates the offset from a mutable pointer.
257257
#[inline(always)]

0 commit comments

Comments
 (0)