]> git.lizzy.rs Git - rust.git/blobdiff - src/doc/guide-lifetimes.md
auto merge of #17432 : nick29581/rust/contrib, r=brson
[rust.git] / src / doc / guide-lifetimes.md
index e92a24f8b94319a68c9246cabe1380b090e8895f..66faee3fa04c802e1ea199603477d95c71ae387e 100644 (file)
@@ -14,9 +14,9 @@ Despite their complete 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.
 
-Although references have rather elaborate theoretical underpinnings usually
-introduced as (e.g. region pointers), the core concepts will be familiar to
-anyone who has worked with C or C++. The best way to explain how they are
+Although references have rather elaborate theoretical underpinnings
+(e.g. region pointers), the core concepts will be familiar to anyone
+who has worked with C or C++. The best way to explain how they are
 used—and their limitations—is probably just to work through several examples.
 
 # By example
@@ -67,7 +67,7 @@ Now we can call `compute_distance()`:
 # let on_the_stack :     Point  =     Point{x: 3.0, y: 4.0};
 # let on_the_heap  : Box<Point> = box Point{x: 7.0, y: 9.0};
 # fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, on_the_heap);
+compute_distance(&on_the_stack, &*on_the_heap);
 ~~~
 
 Here, the `&` operator takes the address of the variable
@@ -77,10 +77,9 @@ value. We also call this _borrowing_ the local variable
 `on_the_stack`, because we have created an alias: that is, another
 name for the same data.
 
-In the case of `on_the_heap`, however, no explicit action is necessary. 
-The compiler will automatically convert a box box point to a reference like &point. 
-This is another form of borrowing; in this case, the contents of the owned box 
-are being lent out.
+Likewise, in the case of `on_the_heap`,
+the `&` operator is used in conjunction with the `*` operator
+to take a reference to the contents of the box.
 
 Whenever a caller lends data to a callee, there are some limitations on what
 the caller can do with the original. For example, if the contents of a
@@ -218,7 +217,7 @@ fn example3() -> int {
 To make this clearer, consider this diagram showing the state of
 memory immediately before the re-assignment of `x`:
 
-~~~ {.notrust}
+~~~ {.text}
     Stack               Exchange Heap
 
   x +-------------+
@@ -232,7 +231,7 @@ memory immediately before the re-assignment of `x`:
 
 Once the reassignment occurs, the memory will look like this:
 
-~~~ {.notrust}
+~~~ {.text}
     Stack               Exchange Heap
 
   x +-------------+          +---------+
@@ -275,8 +274,10 @@ invalidate the pointer `owner_age`.
 
 # Borrowing and enums
 
-The previous example showed that the type system forbids any borrowing
-of owned boxes found in aliasable, mutable memory. This restriction
+The previous example showed that the type system forbids any mutations
+of owned boxed values while they are being borrowed. In general, the type
+system also forbids borrowing a value as mutable if it is already being
+borrowed - either as a mutable reference or an immutable one. This restriction
 prevents pointers from pointing into freed memory. There is one other
 case where the compiler must be very careful to ensure that pointers
 remain valid: pointers into the interior of an `enum`.
@@ -329,7 +330,7 @@ to a pointer of type `&size` into the _interior of the enum_.
 To make this more clear, let's look at a diagram of memory layout in
 the case where `shape` points at a rectangle:
 
-~~~ {.notrust}
+~~~ {.text}
 Stack             Memory
 
 +-------+         +---------------+
@@ -354,7 +355,7 @@ to store that shape value would still be valid, _it would have a
 different type_! The following diagram shows what memory would look
 like if code overwrote `shape` with a circle:
 
-~~~ {.notrust}
+~~~ {.text}
 Stack             Memory
 
 +-------+         +---------------+
@@ -430,36 +431,6 @@ In any case, whatever the lifetime of `r` is, the pointer produced by
 field of a struct is valid as long as the struct is valid. Therefore,
 the compiler accepts the function `get_x()`.
 
-To emphasize this point, let’s look at a variation on the example, this
-time one that does not compile:
-
-~~~ {.ignore}
-struct Point {x: f64, y: f64}
-fn get_x_sh(p: &Point) -> &f64 {
-    &p.x // Error reported here
-}
-~~~
-
-Here, the function `get_x_sh()` takes a reference as input and
-returns a reference. As before, the lifetime of the reference
-that will be returned is a parameter (specified by the
-caller). That means that `get_x_sh()` promises to return a reference
-that is valid for as long as the caller would like: this is
-subtly different from the first example, which promised to return a
-pointer that was valid for as long as its pointer argument was valid.
-
-Within `get_x_sh()`, we see the expression `&p.x` which takes the
-address of a field of a Point. The presence of this expression
-implies that the compiler must guarantee that , so long as the
-resulting pointer is valid, the original Point won't be moved or changed.
-
-But recall that `get_x_sh()` also promised to
-return a pointer that was valid for as long as the caller wanted it to
-be. Clearly, `get_x_sh()` is not in a position to make both of these
-guarantees; in fact, it cannot guarantee that the pointer will remain
-valid at all once it returns, as the parameter `p` may or may not be
-live in the caller. Therefore, the compiler will report an error here.
-
 In general, if you borrow a struct or box to create a
 reference, it will only be valid within the function
 and cannot be returned. This is why the typical way to return references
@@ -575,7 +546,7 @@ This is equivalent to the previous definition.
 Named lifetime notation can also be used to control the flow of execution:
 
 ~~~
-'h: for i in range(0,10) {
+'h: for i in range(0u, 10) {
     'g: loop {
         if i % 2 == 0 { continue 'h; }
         if i == 9 { break 'h; }