Skip to content

Commit 18d4176

Browse files
committed
---
yaml --- r: 153003 b: refs/heads/try2 c: 44ec28c h: refs/heads/master i: 153001: 7a5d031 152999: 6ef9364 v: v3
1 parent d31f361 commit 18d4176

File tree

45 files changed

+1507
-1153
lines changed

Some content is hidden

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

45 files changed

+1507
-1153
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: d6c988a6691545c6065c4b940c0ee2a9bd85bf95
8+
refs/heads/try2: 44ec28cfac9fa3f738e0e77ccca1d804125fd1dd
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/doc/intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ fn main() {
252252
}
253253
```
254254

255-
This will result an error indicating that the value is no longer in scope:
255+
The compiler will produce an error indicating that the value is no longer in scope:
256256

257257
```text
258258
concurrency.rs:12:20: 12:27 error: use of moved value: 'numbers'

branches/try2/src/liballoc/rc.rs

Lines changed: 134 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -10,16 +10,141 @@
1010

1111
/*! Task-local reference-counted boxes (`Rc` type)
1212
13-
The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
14-
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
15-
overhead of atomic reference counting.
13+
The `Rc` type provides shared ownership of an immutable value. Destruction is
14+
deterministic, and will occur as soon as the last owner is gone. It is marked
15+
as non-sendable because it avoids the overhead of atomic reference counting.
1616
17-
The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
18-
pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
19-
freed.
17+
The `downgrade` method can be used to create a non-owning `Weak` pointer to the
18+
box. A `Weak` pointer can be upgraded to an `Rc` pointer, but will return
19+
`None` if the value has already been freed.
2020
21-
For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
22-
pointers, and then storing the parent pointers as `Weak` pointers.
21+
For example, a tree with parent pointers can be represented by putting the
22+
nodes behind strong `Rc` pointers, and then storing the parent pointers as
23+
`Weak` pointers.
24+
25+
26+
## Examples
27+
28+
Consider a scenario where a set of Gadgets are owned by a given Owner. We want
29+
to have our Gadgets point to their Owner. We can't do this with unique
30+
ownership, because more than one gadget may belong to the same Owner. Rc
31+
allows us to share an Owner between multiple Gadgets, and have the Owner kept
32+
alive as long as any Gadget points at it.
33+
34+
```rust
35+
use std::rc::Rc;
36+
37+
struct Owner {
38+
name: String
39+
// ...other fields
40+
}
41+
42+
struct Gadget {
43+
id: int,
44+
owner: Rc<Owner>
45+
// ...other fields
46+
}
47+
48+
fn main() {
49+
// Create a reference counted Owner.
50+
let gadget_owner : Rc<Owner> = Rc::new(
51+
Owner { name: String::from_str("Gadget Man") }
52+
);
53+
54+
// Create Gadgets belonging to gadget_owner. To increment the reference
55+
// count we clone the Rc object.
56+
let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() };
57+
let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() };
58+
59+
drop(gadget_owner);
60+
61+
// Despite dropping gadget_owner, we're still able to print out the name of
62+
// the Owner of the Gadgets. This is because we've only dropped the
63+
// reference count object, not the Owner it wraps. As long as there are
64+
// other Rc objects pointing at the same Owner, it will stay alive. Notice
65+
// that the Rc wrapper around Gadget.owner gets automatically dereferenced
66+
// for us.
67+
println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
68+
println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
69+
70+
// At the end of the method, gadget1 and gadget2 get destroyed, and with
71+
// them the last counted references to our Owner. Gadget Man now gets
72+
// destroyed as well.
73+
}
74+
```
75+
76+
If our requirements change, and we also need to be able to traverse from
77+
Owner->Gadget, we will run into problems: an Rc pointer from Owner->Gadget
78+
introduces a cycle between the objects. This means that their reference counts
79+
can never reach 0, and the objects will stay alive: a memory leak. In order to
80+
get around this, we can use `Weak` pointers. These are reference counted
81+
pointers that don't keep an object alive if there are no normal `Rc` (or
82+
*strong*) pointers left.
83+
84+
Rust actually makes it somewhat difficult to produce this loop in the first
85+
place: in order to end up with two objects that point at each other, one of
86+
them needs to be mutable. This is problematic because Rc enforces memory
87+
safety by only giving out shared references to the object it wraps, and these
88+
don't allow direct mutation. We need to wrap the part of the object we wish to
89+
mutate in a `RefCell`, which provides *interior mutability*: a method to
90+
achieve mutability through a shared reference. `RefCell` enforces Rust's
91+
borrowing rules at runtime. Read the `Cell` documentation for more details on
92+
interior mutability.
93+
94+
```rust
95+
use std::rc::Rc;
96+
use std::rc::Weak;
97+
use std::cell::RefCell;
98+
99+
struct Owner {
100+
name: String,
101+
gadgets: RefCell<Vec<Weak<Gadget>>>
102+
// ...other fields
103+
}
104+
105+
struct Gadget {
106+
id: int,
107+
owner: Rc<Owner>
108+
// ...other fields
109+
}
110+
111+
fn main() {
112+
// Create a reference counted Owner. Note the fact that we've put the
113+
// Owner's vector of Gadgets inside a RefCell so that we can mutate it
114+
// through a shared reference.
115+
let gadget_owner : Rc<Owner> = Rc::new(
116+
Owner {
117+
name: "Gadget Man".to_string(),
118+
gadgets: RefCell::new(Vec::new())
119+
}
120+
);
121+
122+
// Create Gadgets belonging to gadget_owner as before.
123+
let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()});
124+
let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()});
125+
126+
// Add the Gadgets to their Owner. To do this we mutably borrow from
127+
// the RefCell holding the Owner's Gadgets.
128+
gadget_owner.gadgets.borrow_mut().push(gadget1.clone().downgrade());
129+
gadget_owner.gadgets.borrow_mut().push(gadget2.clone().downgrade());
130+
131+
// Iterate over our Gadgets, printing their details out
132+
for gadget_opt in gadget_owner.gadgets.borrow().iter() {
133+
134+
// gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
135+
// that their object is still alive, we need to call upgrade() on them
136+
// to turn them into a strong reference. This returns an Option, which
137+
// contains a reference to our object if it still exists.
138+
let gadget = gadget_opt.upgrade().unwrap();
139+
println!("Gadget {} owned by {}", gadget.id, gadget.owner.name);
140+
}
141+
142+
// At the end of the method, gadget_owner, gadget1 and gadget2 get
143+
// destroyed. There are now no strong (Rc) references to the gadgets.
144+
// Once they get destroyed, the Gadgets get destroyed. This zeroes the
145+
// reference count on Gadget Man, so he gets destroyed as well.
146+
}
147+
```
23148
24149
*/
25150

branches/try2/src/libcollections/str.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ Section: Creating a string
9797
///
9898
/// Returns `Err` with the original vector if the vector contains invalid
9999
/// UTF-8.
100+
///
101+
/// # Example
102+
///
103+
/// ```rust
104+
/// use std::str;
105+
/// let hello_vec = vec![104, 101, 108, 108, 111];
106+
/// let string = str::from_utf8_owned(hello_vec);
107+
/// assert_eq!(string, Ok("hello".to_string()));
108+
/// ```
100109
pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
101110
String::from_utf8(vv)
102111
}
@@ -111,22 +120,39 @@ pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
111120
///
112121
/// ```rust
113122
/// use std::str;
114-
/// let string = str::from_byte(66u8);
115-
/// assert_eq!(string.as_slice(), "B");
123+
/// let string = str::from_byte(104);
124+
/// assert_eq!(string.as_slice(), "h");
116125
/// ```
117126
pub fn from_byte(b: u8) -> String {
118127
assert!(b < 128u8);
119128
String::from_char(1, b as char)
120129
}
121130

122131
/// Convert a char to a string
132+
///
133+
/// # Example
134+
///
135+
/// ```rust
136+
/// use std::str;
137+
/// let string = str::from_char('b');
138+
/// assert_eq!(string.as_slice(), "b");
139+
/// ```
123140
pub fn from_char(ch: char) -> String {
124141
let mut buf = String::new();
125142
buf.push_char(ch);
126143
buf
127144
}
128145

129146
/// Convert a vector of chars to a string
147+
///
148+
/// # Example
149+
///
150+
/// ```rust
151+
/// use std::str;
152+
/// let chars = ['h', 'e', 'l', 'l', 'o'];
153+
/// let string = str::from_chars(chars);
154+
/// assert_eq!(string.as_slice(), "hello");
155+
/// ```
130156
pub fn from_chars(chs: &[char]) -> String {
131157
chs.iter().map(|c| *c).collect()
132158
}

branches/try2/src/libcore/fmt/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,9 @@ impl<'a, T: Show> Show for &'a T {
518518
impl<'a, T: Show> Show for &'a mut T {
519519
fn fmt(&self, f: &mut Formatter) -> Result { secret_show(&**self, f) }
520520
}
521+
impl<'a> Show for &'a Show {
522+
fn fmt(&self, f: &mut Formatter) -> Result { (*self).fmt(f) }
523+
}
521524

522525
impl Bool for bool {
523526
fn fmt(&self, f: &mut Formatter) -> Result {

0 commit comments

Comments
 (0)