about summary refs log tree commit diff
path: root/src/doc/guide-pointers.md
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-27 19:31:46 -0700
committerbors <bors@rust-lang.org>2014-05-27 19:31:46 -0700
commit73dac7e4e61aa88cfc98433b61ba131b38af978d (patch)
tree3ec3b38b9e7929169b43469e8c1a60bcf9a502d8 /src/doc/guide-pointers.md
parent911cc9c35234ab12a4b9a6fc1cb35b52556f242d (diff)
parent0cae84959568859f946dffb1e9d9e1d43e05ae6b (diff)
downloadrust-73dac7e4e61aa88cfc98433b61ba131b38af978d.tar.gz
rust-73dac7e4e61aa88cfc98433b61ba131b38af978d.zip
auto merge of #14387 : alan-andrade/rust/remove_managed_boxes_and_gc, r=brson
My main goals were:
- be clear when we talk about "references" and "pointers"
- remove Managed boxes completely and the concept of GC.

https://github.com/mozilla/rust/issues/13987
Diffstat (limited to 'src/doc/guide-pointers.md')
-rw-r--r--src/doc/guide-pointers.md124
1 files changed, 21 insertions, 103 deletions
diff --git a/src/doc/guide-pointers.md b/src/doc/guide-pointers.md
index 948d033e06c..248142851b7 100644
--- a/src/doc/guide-pointers.md
+++ b/src/doc/guide-pointers.md
@@ -5,7 +5,7 @@ are also one of the more confusing topics for newcomers to Rust. They can also
 be confusing for people coming from other languages that support pointers, such
 as C++. This guide will help you understand this important topic.
 
-# You don't actually need pointers
+# You don't actually need pointers, use references
 
 I have good news for you: you probably don't need to care about pointers,
 especially as you're getting started. Think of it this way: Rust is a language
@@ -75,20 +75,22 @@ pointer that satisfies that use-case:
 
 1. Owned: `Box<Trait>` must be a pointer, because you don't know the size of the
 object, so indirection is mandatory.
+
 2. Owned: You need a recursive data structure. These can be infinite sized, so
 indirection is mandatory.
+
 3. Owned: A very, very, very rare situation in which you have a *huge* chunk of
 data that you wish to pass to many methods. Passing a pointer will make this
 more efficient. If you're coming from another language where this technique is
 common, such as C++, please read "A note..." below.
-4. Managed: Having only a single owner to a piece of data would be inconvenient
-or impossible. This is only often useful when a program is very large or very
-complicated. Using a managed pointer will activate Rust's garbage collection
-mechanism.
-5. Reference: You're writing a function, and you need a pointer, but you don't
+
+4. Reference: You're writing a function, and you need a pointer, but you don't
 care about its ownership. If you make the argument a reference, callers
 can send in whatever kind they want.
 
+5. Shared: You need to share data among tasks. You can achieve that via the
+`Rc` and `Arc` types.
+
 Five exceptions. That's it. Otherwise, you shouldn't need them. Be sceptical
 of pointers in Rust: use them for a deliberate purpose, not just to make the
 compiler happy.
@@ -165,6 +167,7 @@ approximation of owned pointers follows:
 
 1. Only one owned pointer may exist to a particular place in memory. It may be
 borrowed from that owner, however.
+
 2. The Rust compiler uses static analysis to determine where the pointer is in
 scope, and handles allocating and de-allocating that memory. Owned pointers are
 not garbage collected.
@@ -248,81 +251,6 @@ fn main() {
 Now it'll be copying a pointer-sized chunk of memory rather than the whole
 struct.
 
-# Managed Pointers
-
-> **Note**: the `@` form of managed pointers is deprecated and behind a
-> feature gate (it requires a `#![feature(managed_pointers)]` attribute on
-> the crate root). There are replacements, currently
-> there is `std::rc::Rc` and `std::gc::Gc` for shared ownership via reference
-> counting and garbage collection respectively.
-
-Managed pointers, notated by an `@`, are used when having a single owner for
-some data isn't convenient or possible. This generally happens when your
-program is very large and complicated.
-
-For example, let's say you're using an owned pointer, and you want to do this:
-
-~~~rust{.ignore}
-struct Point {
-    x: int,
-    y: int,
-}
-
-fn main() {
-    let a = box Point { x: 10, y: 20 };
-    let b = a;
-    println!("{}", b.x);
-    println!("{}", a.x);
-}
-~~~
-
-You'll get this error:
-
-~~~ {.notrust}
-test.rs:10:20: 10:21 error: use of moved value: `a`
-test.rs:10     println!("{}", a.x);
-                              ^
-note: in expansion of format_args!
-<std-macros>:158:27: 158:81 note: expansion site
-<std-macros>:157:5: 159:6 note: in expansion of println!
-test.rs:10:5: 10:25 note: expansion site
-test.rs:8:9: 8:10 note: `a` moved here because it has type `Box<Point>`, which is moved by default (use `ref` to override)
-test.rs:8     let b = a;
-                  ^
-~~~
-
-As the message says, owned pointers only allow for one owner at a time. When you assign `a` to `b`, `a` becomes invalid. Change your code to this, however:
-
-~~~rust
-struct Point {
-    x: int,
-    y: int,
-}
-
-fn main() {
-    let a = @Point { x: 10, y: 20 };
-    let b = a;
-    println!("{}", b.x);
-    println!("{}", a.x);
-}
-~~~
-
-And it works:
-
-~~~ {.notrust}
-10
-10
-~~~
-
-So why not just use managed pointers everywhere? There are two big drawbacks to
-managed pointers:
-
-1. They activate Rust's garbage collector. Other pointer types don't share this
-drawback.
-2. You cannot pass this data to another task. Shared ownership across
-concurrency boundaries is the source of endless pain in other languages, so
-Rust does not let you do this.
-
 # References
 
 References are the third major kind of pointer Rust supports. They are
@@ -346,7 +274,7 @@ fn compute_distance(p1: &Point, p2: &Point) -> f32 {
 }
 
 fn main() {
-    let origin =    @Point { x: 0.0, y: 0.0 };
+    let origin =    &Point { x: 0.0, y: 0.0 };
     let p1     = box Point { x: 5.0, y: 3.0 };
 
     println!("{:?}", compute_distance(origin, p1));
@@ -354,8 +282,9 @@ fn main() {
 ~~~
 
 This prints `5.83095189`. You can see that the `compute_distance` function
-takes in two references, but we give it a managed and unique pointer. Of
-course, if this were a real program, we wouldn't have any of these pointers,
+takes in two references, a reference to a value on the stack, and a reference
+to a value in a box.
+Of course, if this were a real program, we wouldn't have any of these pointers,
 they're just there to demonstrate the concepts.
 
 So how is this hard? Well, because we're ignoring ownership, the compiler needs
@@ -364,9 +293,11 @@ safety, a reference's representation at runtime is the same as that of
 an ordinary pointer in a C program. They introduce zero overhead. The compiler
 does all safety checks at compile time.
 
-This theory is called 'region pointers,' and involve a concept called
-'lifetimes'. Here's the simple explanation: would you expect this code to
-compile?
+This theory is called 'region pointers' and you can read more about it
+[here](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf).
+Region pointers evolved into what we know today as 'lifetimes'.
+
+Here's the simple explanation: would you expect this code to compile?
 
 ~~~rust{.ignore}
 fn main() {
@@ -461,24 +392,12 @@ fn main() {
 }
 ~~~
 
-This gives you flexibility, without sacrificing performance. For example, this will
-also work:
-
-~~~rust
-fn foo(x: Box<int>) -> int {
-    return *x;
-}
-
-fn main() {
-    let x = box 5;
-    let y = @foo(x);
-}
-~~~
+This gives you flexibility, without sacrificing performance.
 
 You may think that this gives us terrible performance: return a value and then
-immediately box it up?!?! Isn't that the worst of both worlds? Rust is smarter
+immediately box it up ?! Isn't that the worst of both worlds? Rust is smarter
 than that. There is no copy in this code. `main` allocates enough room for the
-`@int`, passes a pointer to that memory into `foo` as `x`, and then `foo` writes
+`box int`, passes a pointer to that memory into `foo` as `x`, and then `foo` writes
 the value straight into that pointer. This writes the return value directly into
 the allocated box.
 
@@ -486,7 +405,6 @@ This is important enough that it bears repeating: pointers are not for optimizin
 returning values from your code. Allow the caller to choose how they want to
 use your output.
 
-
 # Related Resources
 
 * [Lifetimes guide](guide-lifetimes.html)