Skip to content

Commit a224f2f

Browse files
committed
---
yaml --- r: 81983 b: refs/heads/master c: 5d24a1a h: refs/heads/master i: 81981: 934626d 81979: 3f3c8ff 81975: 786e615 81967: ee18e2e 81951: 025ca15 81919: 274cca6 v: v3
1 parent 954a2ba commit a224f2f

File tree

8 files changed

+136
-128
lines changed

8 files changed

+136
-128
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 6c8e6aad7344a62d91d5cf10e0dd1769602a5257
2+
refs/heads/master: 5d24a1ae45189b8222ce84084eaae3ff8b7d67d0
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6c08cc2db4f98e9f07ae7d50338396c4123c2f0a
55
refs/heads/try: 70152ff55722878cde684ee6462c14c65f2c4729

trunk/doc/tutorial.md

Lines changed: 59 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ fn area(sh: Shape) -> float {
737737
match sh {
738738
Circle { radius: radius, _ } => float::consts::pi * square(radius),
739739
Rectangle { top_left: top_left, bottom_right: bottom_right } => {
740-
(bottom_right.x - top_left.x) * (bottom_right.y - top_left.y)
740+
(bottom_right.x - top_left.x) * (top_left.y - bottom_right.y)
741741
}
742742
}
743743
}
@@ -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

trunk/src/etc/emacs/rust-mode-tests.el

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,35 @@ This is some more text. Fee fie fo fum. Humpty dumpty sat on a wall.
196196
*very very very long string
197197
*/"))
198198

199+
(ert-deftest fill-paragraph-single-line-style-with-code-before ()
200+
(test-fill-paragraph
201+
"fn foo() { }
202+
/// This is my comment. This is more of my comment. This is even more."
203+
"fn foo() { }
204+
/// This is my comment. This is
205+
/// more of my comment. This is
206+
/// even more." 14))
207+
208+
(ert-deftest fill-paragraph-single-line-style-with-code-after ()
209+
(test-fill-paragraph
210+
"/// This is my comment. This is more of my comment. This is even more.
211+
fn foo() { }"
212+
"/// This is my comment. This is
213+
/// more of my comment. This is
214+
/// even more.
215+
fn foo() { }" 1 73))
216+
217+
(ert-deftest fill-paragraph-single-line-style-code-before-and-after ()
218+
(test-fill-paragraph
219+
"fn foo() { }
220+
/// This is my comment. This is more of my comment. This is even more.
221+
fn bar() { }"
222+
"fn foo() { }
223+
/// This is my comment. This is
224+
/// more of my comment. This is
225+
/// even more.
226+
fn bar() { }" 14 67))
227+
199228
(defun test-auto-fill (initial position inserted expected)
200229
(rust-test-manip-code
201230
initial

trunk/src/etc/emacs/rust-mode.el

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@
300300
(let
301301
((fill-paragraph-function
302302
(if (not (eq fill-paragraph-function 'rust-fill-paragraph))
303-
fill-paragraph-function)))
303+
fill-paragraph-function))
304+
(fill-paragraph-handle-comment t))
304305
(apply 'fill-paragraph args)
305306
t))))))
306307

trunk/src/librustc/middle/check_match.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -773,12 +773,12 @@ pub fn specialize(cx: &MatchCheckCtxt,
773773
let num_elements = before.len() + after.len();
774774
if num_elements < arity && slice.is_some() {
775775
Some(vec::append(
776-
vec::concat(&[
776+
[
777777
before,
778778
vec::from_elem(
779779
arity - num_elements, wild()),
780780
after
781-
]),
781+
].concat_vec(),
782782
r.tail()
783783
))
784784
} else if num_elements == arity {

trunk/src/librustdoc/clean.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,11 @@ impl Clean<Item> for doctree::Module {
173173
visibility: self.vis.clean(),
174174
id: self.id,
175175
inner: ModuleItem(Module {
176-
items: std::vec::concat(&[self.structs.clean(),
177-
self.enums.clean(), self.fns.clean(),
178-
std::vec::concat(self.foreigns.clean()),
179-
self.mods.clean(), self.typedefs.clean(),
180-
self.statics.clean(), self.traits.clean(),
181-
self.impls.clean(), self.view_items.clean()])
176+
items: [self.structs.clean(), self.enums.clean(),
177+
self.fns.clean(), self.foreigns.clean().concat_vec(),
178+
self.mods.clean(), self.typedefs.clean(),
179+
self.statics.clean(), self.traits.clean(),
180+
self.impls.clean(), self.view_items.clean()].concat_vec()
182181
})
183182
}
184183
}

trunk/src/libstd/rt/sched.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,6 @@ mod test {
12801280
// FIXME: #9407: xfail-test
12811281
fn dont_starve_1() {
12821282
use rt::comm::oneshot;
1283-
use unstable::running_on_valgrind;
12841283

12851284
do stress_factor().times {
12861285
do run_in_mt_newsched_task {

trunk/src/libstd/vec.rs

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -340,59 +340,36 @@ pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
340340
result
341341
}
342342

343-
/// Flattens a vector of vectors of T into a single vector of T.
344-
pub fn concat<T:Clone>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
345-
346-
/// Concatenate a vector of vectors, placing a given separator between each
347-
pub fn connect<T:Clone>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
348-
349-
/// Flattens a vector of vectors of T into a single vector of T.
350-
pub fn concat_slices<T:Clone>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
351-
352-
/// Concatenate a vector of vectors, placing a given separator between each
353-
pub fn connect_slices<T:Clone>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
354-
355343
#[allow(missing_doc)]
356344
pub trait VectorVector<T> {
357345
// FIXME #5898: calling these .concat and .connect conflicts with
358346
// StrVector::con{cat,nect}, since they have generic contents.
347+
/// Flattens a vector of vectors of T into a single vector of T.
359348
fn concat_vec(&self) -> ~[T];
360-
fn connect_vec(&self, sep: &T) -> ~[T];
361-
}
362-
363-
impl<'self, T:Clone> VectorVector<T> for &'self [~[T]] {
364-
/// Flattens a vector of slices of T into a single vector of T.
365-
fn concat_vec(&self) -> ~[T] {
366-
self.flat_map(|inner| (*inner).clone())
367-
}
368349

369350
/// Concatenate a vector of vectors, placing a given separator between each.
370-
fn connect_vec(&self, sep: &T) -> ~[T] {
371-
let mut r = ~[];
372-
let mut first = true;
373-
for inner in self.iter() {
374-
if first { first = false; } else { r.push((*sep).clone()); }
375-
r.push_all((*inner).clone());
376-
}
377-
r
378-
}
351+
fn connect_vec(&self, sep: &T) -> ~[T];
379352
}
380353

381-
impl<'self,T:Clone> VectorVector<T> for &'self [&'self [T]] {
382-
/// Flattens a vector of slices of T into a single vector of T.
354+
impl<'self, T: Clone, V: Vector<T>> VectorVector<T> for &'self [V] {
383355
fn concat_vec(&self) -> ~[T] {
384-
self.flat_map(|&inner| inner.to_owned())
356+
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
357+
let mut result = with_capacity(size);
358+
for v in self.iter() {
359+
result.push_all(v.as_slice())
360+
}
361+
result
385362
}
386363

387-
/// Concatenate a vector of slices, placing a given separator between each.
388364
fn connect_vec(&self, sep: &T) -> ~[T] {
389-
let mut r = ~[];
365+
let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
366+
let mut result = with_capacity(size + self.len());
390367
let mut first = true;
391-
for &inner in self.iter() {
392-
if first { first = false; } else { r.push((*sep).clone()); }
393-
r.push_all(inner);
368+
for v in self.iter() {
369+
if first { first = false } else { result.push(sep.clone()) }
370+
result.push_all(v.as_slice())
394371
}
395-
r
372+
result
396373
}
397374
}
398375

@@ -3109,24 +3086,21 @@ mod tests {
31093086

31103087
#[test]
31113088
fn test_concat() {
3112-
assert_eq!(concat([~[1], ~[2,3]]), ~[1, 2, 3]);
3089+
let v: [~[int], ..0] = [];
3090+
assert_eq!(v.concat_vec(), ~[]);
31133091
assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
31143092

3115-
assert_eq!(concat_slices([&[1], &[2,3]]), ~[1, 2, 3]);
31163093
assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
31173094
}
31183095

31193096
#[test]
31203097
fn test_connect() {
3121-
assert_eq!(connect([], &0), ~[]);
3122-
assert_eq!(connect([~[1], ~[2, 3]], &0), ~[1, 0, 2, 3]);
3123-
assert_eq!(connect([~[1], ~[2], ~[3]], &0), ~[1, 0, 2, 0, 3]);
3098+
let v: [~[int], ..0] = [];
3099+
assert_eq!(v.connect_vec(&0), ~[]);
31243100
assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
31253101
assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
31263102

3127-
assert_eq!(connect_slices([], &0), ~[]);
3128-
assert_eq!(connect_slices([&[1], &[2, 3]], &0), ~[1, 0, 2, 3]);
3129-
assert_eq!(connect_slices([&[1], &[2], &[3]], &0), ~[1, 0, 2, 0, 3]);
3103+
assert_eq!(v.connect_vec(&0), ~[]);
31303104
assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
31313105
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
31323106
}
@@ -3758,7 +3732,9 @@ mod tests {
37583732
#[cfg(test)]
37593733
mod bench {
37603734
use extra::test::BenchHarness;
3735+
use iter::range;
37613736
use vec;
3737+
use vec::VectorVector;
37623738
use option::*;
37633739

37643740
#[bench]
@@ -3798,4 +3774,20 @@ mod bench {
37983774
xs + ys;
37993775
}
38003776
}
3777+
3778+
#[bench]
3779+
fn concat(bh: &mut BenchHarness) {
3780+
let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
3781+
do bh.iter {
3782+
xss.concat_vec();
3783+
}
3784+
}
3785+
3786+
#[bench]
3787+
fn connect(bh: &mut BenchHarness) {
3788+
let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
3789+
do bh.iter {
3790+
xss.connect_vec(&0);
3791+
}
3792+
}
38013793
}

0 commit comments

Comments
 (0)