Skip to content

Commit 565ec93

Browse files
committed
auto merge of #5110 : pcwalton/rust/and-const, r=pcwalton
r? @brson
2 parents 6439e28 + c9dd917 commit 565ec93

File tree

71 files changed

+294
-691
lines changed

Some content is hidden

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

71 files changed

+294
-691
lines changed

doc/rust.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,11 +1610,11 @@ The following are examples of structure expressions:
16101610
~~~~
16111611
# struct Point { x: float, y: float }
16121612
# struct TuplePoint(float, float);
1613-
# mod game { pub struct User { name: &str, age: uint, mut score: uint } }
1613+
# mod game { pub struct User { name: &str, age: uint, score: uint } }
16141614
# use game;
16151615
Point {x: 10f, y: 20f};
16161616
TuplePoint(10f, 20f);
1617-
let u = game::User {name: "Joe", age: 35u, mut score: 100_000};
1617+
let u = game::User {name: "Joe", age: 35u, score: 100_000};
16181618
~~~~
16191619

16201620
A structure expression forms a new value of the named structure type.

doc/tutorial-borrowed-ptr.md

Lines changed: 4 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,12 @@ mutations:
348348
~~~ {.xfail-test}
349349
fn example3() -> int {
350350
struct R { g: int }
351-
struct S { mut f: ~R }
351+
struct S { f: ~R }
352352
353-
let mut x = ~S {mut f: ~R {g: 3}};
353+
let mut x = ~S {f: ~R {g: 3}};
354354
let y = &x.f.g;
355-
x = ~S {mut f: ~R {g: 4}}; // Error reported here.
356-
x.f = ~R {g: 5}; // Error reported here.
355+
x = ~S {f: ~R {g: 4}}; // Error reported here.
356+
x.f = ~R {g: 5}; // Error reported here.
357357
*y
358358
}
359359
~~~
@@ -362,91 +362,6 @@ In this case, two errors are reported, one when the variable `x` is
362362
modified and another when `x.f` is modified. Either modification would
363363
invalidate the pointer `y`.
364364

365-
Things get trickier when the unique box is not uniquely owned by the
366-
stack frame, or when there is no way for the compiler to determine the
367-
box's owner. Consider a program like this:
368-
369-
~~~ {.xfail-test}
370-
struct R { g: int }
371-
struct S { mut f: ~R }
372-
fn example5a(x: @S, callback: @fn()) -> int {
373-
let y = &x.f.g; // Error reported here.
374-
...
375-
callback();
376-
...
377-
# return 0;
378-
}
379-
~~~
380-
381-
Here the heap looks something like:
382-
383-
~~~ {.notrust}
384-
Stack Managed Heap Exchange Heap
385-
386-
x +------+ +-------------+ +------+
387-
| @... | ----> | mut f: ~... | --+-> | g: 3 |
388-
y +------+ +-------------+ | +------+
389-
| &int | -------------------------+
390-
+------+
391-
~~~
392-
393-
In this case, the owning reference to the value being borrowed is
394-
`x.f`. Moreover, `x.f` is both mutable and *aliasable*. Aliasable
395-
means that there may be other pointers to that same managed box, so
396-
even if the compiler were to prove an absence of mutations to `x.f`,
397-
code could mutate `x.f` indirectly by changing an alias of
398-
`x`. Therefore, to be safe, the compiler only accepts *pure* actions
399-
during the lifetime of `y`. We define what "pure" means in the section
400-
on [purity](#purity).
401-
402-
Besides ensuring purity, the only way to borrow the interior of a
403-
unique found in aliasable memory is to ensure that the borrowed field
404-
itself is also unique, as in the following example:
405-
406-
~~~
407-
struct R { g: int }
408-
struct S { f: ~R }
409-
fn example5b(x: @S) -> int {
410-
let y = &x.f.g;
411-
...
412-
# return 0;
413-
}
414-
~~~
415-
416-
Here, the field `f` is not declared as mutable. But that is enough for
417-
the compiler to know that, even if aliases to `x` exist, the field `f`
418-
cannot be changed and hence the unique box `g` will remain valid.
419-
420-
If you do have a unique box in a mutable field, and you wish to borrow
421-
it, one option is to use the swap operator to move that unique box
422-
onto your stack:
423-
424-
~~~
425-
struct R { g: int }
426-
struct S { mut f: ~R }
427-
fn example5c(x: @S) -> int {
428-
let mut v = ~R {g: 0};
429-
v <-> x.f; // Swap v and x.f
430-
{ // Block constrains the scope of `y`:
431-
let y = &v.g;
432-
...
433-
}
434-
x.f = v; // Replace x.f
435-
...
436-
# return 0;
437-
}
438-
~~~
439-
440-
Of course, this has the side effect of modifying your managed box for
441-
the duration of the borrow, so it only works when you know that you
442-
won't be accessing that same box for the duration of the loan. Also,
443-
it is sometimes necessary to introduce additional blocks to constrain
444-
the scope of the loan. In this example, the borrowed pointer `y`
445-
would still be in scope when you moved the value `v` back into `x.f`,
446-
and hence moving `v` would be considered illegal. You cannot move
447-
values if they are the targets of valid outstanding loans. Introducing
448-
the block restricts the scope of `y`, making the move legal.
449-
450365
# Borrowing and enums
451366

452367
The previous example showed that the type system forbids any borrowing
@@ -558,11 +473,6 @@ permit `ref` bindings into data owned by the stack frame even if the
558473
data are mutable, but otherwise it requires that the data reside in
559474
immutable memory.
560475

561-
> ***Note:*** Right now, pattern bindings not explicitly annotated
562-
> with `ref` or `copy` use a special mode of "implicit by reference".
563-
> This is changing as soon as we finish updating all the existing code
564-
> in the compiler that relies on the current settings.
565-
566476
# Returning borrowed pointers
567477

568478
So far, all of the examples we've looked at use borrowed pointers in a
@@ -745,69 +655,6 @@ fn select<T>(shape: &Shape, threshold: float,
745655

746656
This is equivalent to the previous definition.
747657

748-
# Purity
749-
750-
As mentioned before, the Rust compiler offers a kind of escape hatch
751-
that permits borrowing of any data, as long as the actions that occur
752-
during the lifetime of the borrow are pure. Pure actions are those
753-
that only modify data owned by the current stack frame. The compiler
754-
can therefore permit arbitrary pointers into the heap, secure in the
755-
knowledge that no pure action will ever cause them to become
756-
invalidated (the compiler must still track data on the stack which is
757-
borrowed and enforce those rules normally, of course). A pure function
758-
in Rust is referentially transparent: it returns the same results
759-
given the same (observably equivalent) inputs. That is because while
760-
pure functions are allowed to modify data, they may only modify
761-
*stack-local* data, which cannot be observed outside the scope of the
762-
function itself. (Using an `unsafe` block invalidates this guarantee.)
763-
764-
Let’s revisit a previous example and show how purity can affect
765-
typechecking. Here is `example5a()`, which borrows the interior of a
766-
unique box found in an aliasable, mutable location, only now we’ve
767-
replaced the `...` with some specific code:
768-
769-
~~~
770-
struct R { g: int }
771-
struct S { mut f: ~R }
772-
fn example5a(x: @S ...) -> int {
773-
let y = &x.f.g; // Unsafe
774-
*y + 1
775-
}
776-
~~~
777-
778-
The new code simply returns an incremented version of `y`. This code
779-
clearly doesn't mutate the heap, so the compiler is satisfied.
780-
781-
But suppose we wanted to pull the increment code into a helper, like
782-
this:
783-
784-
~~~
785-
fn add_one(x: &int) -> int { *x + 1 }
786-
~~~
787-
788-
We can now update `example5a()` to use `add_one()`:
789-
790-
~~~
791-
# struct R { g: int }
792-
# struct S { mut f: ~R }
793-
# pure fn add_one(x: &int) -> int { *x + 1 }
794-
fn example5a(x: @S ...) -> int {
795-
let y = &x.f.g;
796-
add_one(y) // Error reported here
797-
}
798-
~~~
799-
800-
But now the compiler will report an error again. The reason is that it
801-
only considers one function at a time (like most typecheckers), and
802-
so it does not know that `add_one()` consists of pure code. We can
803-
help the compiler by labeling `add_one()` as pure:
804-
805-
~~~
806-
pure fn add_one(x: &int) -> int { *x + 1 }
807-
~~~
808-
809-
With this change, the modified version of `example5a()` will again compile.
810-
811658
# Conclusion
812659

813660
So there you have it: a (relatively) brief tour of the borrowed pointer

doc/tutorial-ffi.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,21 +220,21 @@ extern mod std;
220220
use libc::c_ulonglong;
221221
222222
struct timeval {
223-
mut tv_sec: c_ulonglong,
224-
mut tv_usec: c_ulonglong
223+
tv_sec: c_ulonglong,
224+
tv_usec: c_ulonglong
225225
}
226226
227227
#[nolink]
228228
extern mod lib_c {
229-
fn gettimeofday(tv: *timeval, tz: *()) -> i32;
229+
fn gettimeofday(tv: *mut timeval, tz: *()) -> i32;
230230
}
231231
fn unix_time_in_microseconds() -> u64 {
232232
unsafe {
233-
let x = timeval {
234-
mut tv_sec: 0 as c_ulonglong,
235-
mut tv_usec: 0 as c_ulonglong
233+
let mut x = timeval {
234+
tv_sec: 0 as c_ulonglong,
235+
tv_usec: 0 as c_ulonglong
236236
};
237-
lib_c::gettimeofday(ptr::addr_of(&x), ptr::null());
237+
lib_c::gettimeofday(&mut x, ptr::null());
238238
return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64);
239239
}
240240
}

doc/tutorial.md

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -583,19 +583,16 @@ Inherited mutability means that any field of a struct may be mutable, if the
583583
struct is in a mutable slot (or a field of a struct in a mutable slot, and
584584
so forth).
585585

586-
A struct that is not mutable due to inherited mutability may declare some
587-
of its fields nevertheless mutable, using the `mut` keyword.
588-
589586
~~~~
590587
struct Stack {
591588
content: ~[int],
592-
mut head: uint
589+
head: uint
593590
}
594591
~~~~
595592

596-
With a value of such a type, you can do `mystack.head += 1`. If `mut` were
597-
omitted from the type, such an assignment to a struct without inherited
598-
mutability would result in a type error.
593+
With a value (say, `mystack`) of such a type in a mutable location, you can do
594+
`mystack.head += 1`. But in an immutable location, such an assignment to a
595+
struct without inherited mutability would result in a type error.
599596

600597
`match` patterns destructure structs. The basic syntax is
601598
`Name { fieldname: pattern, ... }`:
@@ -938,19 +935,19 @@ type that contains managed boxes or other managed types.
938935
~~~
939936
// A linked list node
940937
struct Node {
941-
mut next: MaybeNode,
942-
mut prev: MaybeNode,
938+
next: MaybeNode,
939+
prev: MaybeNode,
943940
payload: int
944941
}
945942
946943
enum MaybeNode {
947-
SomeNode(@Node),
944+
SomeNode(@mut Node),
948945
NoNode
949946
}
950947
951-
let node1 = @Node { next: NoNode, prev: NoNode, payload: 1 };
952-
let node2 = @Node { next: NoNode, prev: NoNode, payload: 2 };
953-
let node3 = @Node { next: NoNode, prev: NoNode, payload: 3 };
948+
let node1 = @mut Node { next: NoNode, prev: NoNode, payload: 1 };
949+
let node2 = @mut Node { next: NoNode, prev: NoNode, payload: 2 };
950+
let node3 = @mut Node { next: NoNode, prev: NoNode, payload: 3 };
954951
955952
// Link the three list nodes together
956953
node1.next = SomeNode(node2);
@@ -2300,8 +2297,8 @@ mod farm {
23002297
# impl Human { fn rest(&self) { } }
23012298
# pub fn make_me_a_farm() -> farm::Farm { farm::Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
23022299
pub struct Farm {
2303-
priv mut chickens: ~[Chicken],
2304-
priv mut cows: ~[Cow],
2300+
priv chickens: ~[Chicken],
2301+
priv cows: ~[Cow],
23052302
farmer: Human
23062303
}
23072304

src/libstd/cell.rs renamed to src/libcore/cell.rs

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

11-
use core::option;
12-
use core::prelude::*;
11+
use option;
12+
use prelude::*;
1313

1414
/// A dynamic, mutable location.
1515
///

src/libcore/core.rc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue:
5151
#[warn(vecs_implicitly_copyable)];
5252
#[deny(non_camel_case_types)];
5353
#[allow(deprecated_self)];
54+
#[allow(deprecated_mutable_fields)];
5455

5556
/* The Prelude. */
5657

@@ -142,6 +143,7 @@ pub mod dlist;
142143
#[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"]
143144
pub mod dlist_iter;
144145
pub mod hashmap;
146+
pub mod cell;
145147

146148

147149
/* Tasks and communication */

src/libcore/pipes.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ bounded and unbounded protocols allows for less code duplication.
8686

8787
use cmp::Eq;
8888
use cast::{forget, reinterpret_cast, transmute};
89+
use cell::Cell;
8990
use either::{Either, Left, Right};
9091
use kinds::Owned;
9192
use libc;
@@ -917,11 +918,9 @@ pub fn spawn_service<T:Owned,Tb:Owned>(
917918
918919
// This is some nasty gymnastics required to safely move the pipe
919920
// into a new task.
920-
let server = ~mut Some(server);
921-
do task::spawn || {
922-
let mut server_ = None;
923-
server_ <-> *server;
924-
service(option::unwrap(server_))
921+
let server = Cell(server);
922+
do task::spawn {
923+
service(server.take());
925924
}
926925
927926
client
@@ -941,11 +940,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(
941940
942941
// This is some nasty gymnastics required to safely move the pipe
943942
// into a new task.
944-
let server = ~mut Some(server);
945-
do task::spawn || {
946-
let mut server_ = None;
947-
server_ <-> *server;
948-
service(option::unwrap(server_))
943+
let server = Cell(server);
944+
do task::spawn {
945+
service(server.take())
949946
}
950947
951948
client

0 commit comments

Comments
 (0)