Skip to content

Commit 1eadb0d

Browse files
committed
---
yaml --- r: 95038 b: refs/heads/dist-snap c: c685e08 h: refs/heads/master v: v3
1 parent 2b02d7b commit 1eadb0d

File tree

3 files changed

+61
-79
lines changed

3 files changed

+61
-79
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 9883a6250b61eb4bb715684f9b25304f4f0d437e
9+
refs/heads/dist-snap: c685e0879c485f3ff44bf46aeaf24f114bf9d097
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/doc/tutorial.md

Lines changed: 58 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -923,60 +923,22 @@ custom destructors.
923923

924924
# Boxes
925925

926-
A value in Rust is stored directly inside the owner. If a `struct` contains
927-
four `int` fields, it will be four times as large as a single `int`. The
928-
following `struct` type is invalid, as it would have an infinite size:
926+
Many modern languages represent values as pointers to heap memory by
927+
default. In contrast, Rust, like C and C++, represents such types directly.
928+
Another way to say this is that aggregate data in Rust are *unboxed*. This
929+
means that if you `let x = Point { x: 1f, y: 1f };`, you are creating a struct
930+
on the stack. If you then copy it into a data structure, you copy the entire
931+
struct, not just a pointer.
929932

930-
~~~~ {.xfail-test}
931-
struct List {
932-
next: Option<List>,
933-
data: int
934-
}
935-
~~~~
936-
937-
> ***Note:*** The `Option` type is an enum representing an *optional* value.
938-
> It's comparable to a nullable pointer in many other languages, but stores the
939-
> contained value unboxed.
940-
941-
An *owned box* (`~`) uses a heap allocation to provide the invariant of always
942-
being the size of a pointer, regardless of the contained type. This can be
943-
leveraged to create a valid recursive `struct` type with a finite size:
944-
945-
~~~~
946-
struct List {
947-
next: Option<~List>,
948-
data: int
949-
}
950-
~~~~
951-
952-
Since an owned box has a single owner, they are limited to representing
953-
tree-like data structures.
954-
955-
The most common use case for owned boxes is creating recursive data structures
956-
like a binary search tree. Rust's trait-based generics system (covered later in
957-
the tutorial) is usually used for static dispatch, but also provides dynamic
958-
dispatch via boxing. Values of different types may have different sizes, but a
959-
box is able to *erase* the difference via the layer of indirection they
960-
provide.
933+
For small structs like `Point`, this is usually more efficient than allocating
934+
memory and indirecting through a pointer. But for big structs, or mutable
935+
state, it can be useful to have a single copy on the stack or on the heap, and
936+
refer to that through a pointer.
961937

962-
In uncommon cases, the indirection can provide a performance gain or memory
963-
reduction by making values smaller. However, unboxed values should almost
964-
always be preferred.
938+
## Owned boxes
965939

966-
Note that returning large unboxed values via boxes is unnecessary. A large
967-
value is returned via a hidden output parameter, and the decision on where to
968-
place the return value should be left to the caller:
969-
970-
~~~~
971-
fn foo() -> (int, int, int, int, int, int) {
972-
(5, 5, 5, 5, 5, 5)
973-
}
974-
975-
let x = ~foo(); // allocates, and writes the integers directly to it
976-
~~~~
977-
978-
Beyond the properties granted by the size, an owned box behaves as a regular
979-
value by inheriting the mutability and lifetime of the owner:
940+
An owned box (`~`) is a uniquely owned allocation on the heap. It inherits the
941+
mutability and lifetime of the owner as it would if there was no box:
980942

981943
~~~~
982944
let x = 5; // immutable
@@ -988,33 +950,35 @@ let mut y = ~5; // mutable
988950
*y += 2; // the * operator is needed to access the contained value
989951
~~~~
990952

991-
As covered earlier, an owned box has a destructor to clean up the allocated
992-
memory. This makes it more restricted than an unboxed type with no destructor
993-
by introducing *move semantics*.
953+
The purpose of an owned box is to add a layer of indirection in order to create
954+
recursive data structures or cheaply pass around an object larger than a
955+
pointer. Since an owned box has a unique owner, it can only be used to
956+
represent a tree data structure.
994957

995-
# Move semantics
958+
The following struct won't compile, because the lack of indirection would mean
959+
it has an infinite size:
996960

997-
Rust uses a shallow copy for parameter passing, assignment and returning from
998-
functions. This is considered a move of ownership for types with destructors.
999-
After a value has been moved, it can no longer be used from the source location
1000-
and will not be destroyed when the source goes out of scope.
1001-
1002-
~~~~
1003-
let x = ~5;
1004-
let y = x.clone(); // y is a newly allocated box
1005-
let z = x; // no new memory allocated, x can no longer be used
961+
~~~~ {.xfail-test}
962+
struct Foo {
963+
child: Option<Foo>
964+
}
1006965
~~~~
1007966

1008-
The mutability of a value may be changed by moving it to a new owner:
967+
> ***Note:*** The `Option` type is an enum that represents an *optional* value.
968+
> It's comparable to a nullable pointer in many other languages, but stores the
969+
> contained value unboxed.
970+
971+
Adding indirection with an owned pointer allocates the child outside of the
972+
struct on the heap, which makes it a finite size and won't result in a
973+
compile-time error:
1009974

1010975
~~~~
1011-
let r = ~13;
1012-
let mut s = r; // box becomes mutable
1013-
*s += 1;
1014-
let t = s; // box becomes immutable
976+
struct Foo {
977+
child: Option<~Foo>
978+
}
1015979
~~~~
1016980

1017-
# Managed boxes
981+
## Managed boxes
1018982

1019983
A managed box (`@`) is a heap allocation with the lifetime managed by a
1020984
task-local garbage collector. It will be destroyed at some point after there
@@ -1059,6 +1023,30 @@ d = b; // box type is the same, okay
10591023
c = b; // error
10601024
~~~~
10611025

1026+
# Move semantics
1027+
1028+
Rust uses a shallow copy for parameter passing, assignment and returning values
1029+
from functions. A shallow copy is considered a move of ownership if the
1030+
ownership tree of the copied value includes an owned box or a type with a
1031+
custom destructor. After a value has been moved, it can no longer be used from
1032+
the source location and will not be destroyed there.
1033+
1034+
~~~~
1035+
let x = ~5;
1036+
let y = x.clone(); // y is a newly allocated box
1037+
let z = x; // no new memory allocated, x can no longer be used
1038+
~~~~
1039+
1040+
Since in owned boxes mutability is a property of the owner, not the
1041+
box, mutable boxes may become immutable when they are moved, and vice-versa.
1042+
1043+
~~~~
1044+
let r = ~13;
1045+
let mut s = r; // box becomes mutable
1046+
*s += 1;
1047+
let t = s; // box becomes immutable
1048+
~~~~
1049+
10621050
# Borrowed pointers
10631051

10641052
Rust's borrowed pointers are a general purpose reference type. In contrast with

branches/dist-snap/src/librustpkg/rustpkg.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -620,14 +620,8 @@ impl CtxMethods for BuildContext {
620620
match built_test_in_workspace(pkgid, workspace) {
621621
Some(test_exec) => {
622622
debug!("test: test_exec = %s", test_exec.to_str());
623-
let p_output = run::process_output(test_exec.to_str(), [~"--test"]);
624-
if p_output.status == 0 {
625-
println(str::from_utf8(p_output.output));
626-
}
627-
else {
628-
println(str::from_utf8(p_output.error));
629-
}
630-
os::set_exit_status(p_output.status);
623+
let status = run::process_status(test_exec.to_str(), [~"--test"]);
624+
os::set_exit_status(status);
631625
}
632626
None => {
633627
error(fmt!("Internal error: test executable for package ID %s in workspace %s \

0 commit comments

Comments
 (0)