1 # Japanese translations for Rust package
2 # Copyright (C) 2013 The Rust Project Developers
3 # This file is distributed under the same license as the Rust package.
4 # Automatically generated, 2013.
8 "Project-Id-Version: Rust 0.8\n"
9 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
10 "PO-Revision-Date: 2013-07-28 20:32+0900\n"
11 "Last-Translator: Automatically generated\n"
12 "Language-Team: none\n"
15 "Content-Type: text/plain; charset=UTF-8\n"
16 "Content-Transfer-Encoding: 8bit\n"
17 "Plural-Forms: nplurals=1; plural=0;\n"
20 #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4
21 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4
22 #: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4
23 msgid "# Introduction"
27 #: doc/tutorial.md:1108 doc/tutorial-borrowed-ptr.md:72
28 msgid "Now we can call `compute_distance()` in various ways:"
30 "上記の `compute_distance()` 関数は、様々な方法で呼び出すことができます。"
33 #: doc/tutorial-borrowed-ptr.md:2
34 msgid "% Rust Borrowed Pointers Tutorial"
38 #: doc/tutorial-borrowed-ptr.md:14
40 "Borrowed pointers are one of the more flexible and powerful tools available "
41 "in Rust. A borrowed pointer can point anywhere: into the managed or exchange "
42 "heap, into the stack, and even into the interior of another data structure. "
43 "A borrowed pointer is as flexible as a C pointer or C++ reference. However, "
44 "unlike C and C++ compilers, the Rust compiler includes special static checks "
45 "that ensure that programs use borrowed pointers safely. Another advantage of "
46 "borrowed pointers is that they are invisible to the garbage collector, so "
47 "working with borrowed pointers helps reduce the overhead of automatic memory "
52 #: doc/tutorial-borrowed-ptr.md:18
54 "Despite their complete safety, a borrowed pointer's representation at "
55 "runtime is the same as that of an ordinary pointer in a C program. They "
56 "introduce zero overhead. The compiler does all safety checks at compile time."
60 #: doc/tutorial-borrowed-ptr.md:24
62 "Although borrowed pointers have rather elaborate theoretical underpinnings "
63 "(region pointers), the core concepts will be familiar to anyone who has "
64 "worked with C or C++. Therefore, the best way to explain how they are used—"
65 "and their limitations—is probably just to work through several examples."
69 #: doc/tutorial-borrowed-ptr.md:26
74 #: doc/tutorial-borrowed-ptr.md:31
76 "Borrowed pointers are called *borrowed* because they are only valid for a "
77 "limited duration. Borrowed pointers never claim any kind of ownership over "
78 "the data that they point to: instead, they are used for cases where you "
79 "would like to use data for a short time."
83 #: doc/tutorial-borrowed-ptr.md:33
84 msgid "As an example, consider a simple struct type `Point`:"
88 #: doc/tutorial-borrowed-ptr.md:37
89 msgid "~~~ struct Point {x: float, y: float} ~~~"
93 #: doc/tutorial-borrowed-ptr.md:41
95 "We can use this simple definition to allocate points in many different ways. "
96 "For example, in this code, each of these three local variables contains a "
97 "point, but allocated in a different place:"
101 #: doc/tutorial-borrowed-ptr.md:48
105 "# struct Point {x: float, y: float}\n"
106 "let on_the_stack : Point = Point {x: 3.0, y: 4.0};\n"
107 "let managed_box : @Point = @Point {x: 5.0, y: 1.0};\n"
108 "let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};\n"
113 #: doc/tutorial-borrowed-ptr.md:60
115 "Suppose we wanted to write a procedure that computed the distance between "
116 "any two points, no matter where they were stored. For example, we might like "
117 "to compute the distance between `on_the_stack` and `managed_box`, or between "
118 "`managed_box` and `owned_box`. One option is to define a function that takes "
119 "two arguments of type `Point`—that is, it takes the points by value. But if "
120 "we define it this way, calling the function will cause the points to be "
121 "copied. For points, this is probably not so bad, but often copies are "
122 "expensive. Worse, if the data type contains mutable fields, copying can "
123 "change the semantics of your program in unexpected ways. So we'd like to "
124 "define a function that takes the points by pointer. We can use borrowed "
125 "pointers to do this:"
129 #: doc/tutorial-borrowed-ptr.md:70
133 "# struct Point {x: float, y: float}\n"
134 "# fn sqrt(f: float) -> float { 0f }\n"
135 "fn compute_distance(p1: &Point, p2: &Point) -> float {\n"
136 " let x_d = p1.x - p2.x;\n"
137 " let y_d = p1.y - p2.y;\n"
138 " sqrt(x_d * x_d + y_d * y_d)\n"
144 #: doc/tutorial-borrowed-ptr.md:82
148 "# struct Point {x: float, y: float}\n"
149 "# let on_the_stack : Point = Point{x: 3.0, y: 4.0};\n"
150 "# let managed_box : @Point = @Point{x: 5.0, y: 1.0};\n"
151 "# let owned_box : ~Point = ~Point{x: 7.0, y: 9.0};\n"
152 "# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }\n"
153 "compute_distance(&on_the_stack, managed_box);\n"
154 "compute_distance(managed_box, owned_box);\n"
159 #: doc/tutorial-borrowed-ptr.md:89
161 "Here, the `&` operator takes the address of the variable `on_the_stack`; "
162 "this is because `on_the_stack` has the type `Point` (that is, a struct "
163 "value) and we have to take its address to get a value. We also call this "
164 "_borrowing_ the local variable `on_the_stack`, because we have created an "
165 "alias: that is, another name for the same data."
169 #: doc/tutorial-borrowed-ptr.md:95
171 "In contrast, we can pass the boxes `managed_box` and `owned_box` to "
172 "`compute_distance` directly. The compiler automatically converts a box like "
173 "`@Point` or `~Point` to a borrowed pointer like `&Point`. This is another "
174 "form of borrowing: in this case, the caller lends the contents of the "
175 "managed or owned box to the callee."
179 #: doc/tutorial-borrowed-ptr.md:105
181 "Whenever a caller lends data to a callee, there are some limitations on what "
182 "the caller can do with the original. For example, if the contents of a "
183 "variable have been lent out, you cannot send that variable to another task. "
184 "In addition, the compiler will reject any code that might cause the borrowed "
185 "value to be freed or overwrite its component fields with values of different "
186 "types (I'll get into what kinds of actions those are shortly). This rule "
187 "should make intuitive sense: you must wait for a borrower to return the "
188 "value that you lent it (that is, wait for the borrowed pointer to go out of "
189 "scope) before you can make full use of it again."
193 #: doc/tutorial-borrowed-ptr.md:107
194 msgid "# Other uses for the & operator"
198 #: doc/tutorial-borrowed-ptr.md:109
199 msgid "In the previous example, the value `on_the_stack` was defined like so:"
203 #: doc/tutorial-borrowed-ptr.md:114
205 "~~~ # struct Point {x: float, y: float} let on_the_stack: Point = Point {x: "
210 #: doc/tutorial-borrowed-ptr.md:119
212 "This declaration means that code can only pass `Point` by value to other "
213 "functions. As a consequence, we had to explicitly take the address of "
214 "`on_the_stack` to get a borrowed pointer. Sometimes however it is more "
215 "convenient to move the & operator into the definition of `on_the_stack`:"
219 #: doc/tutorial-borrowed-ptr.md:124
221 "~~~ # struct Point {x: float, y: float} let on_the_stack2: &Point = &Point "
222 "{x: 3.0, y: 4.0}; ~~~"
226 #: doc/tutorial-borrowed-ptr.md:128
228 "Applying `&` to an rvalue (non-assignable location) is just a convenient "
229 "shorthand for creating a temporary and taking its address. A more verbose "
230 "way to write the same code is:"
234 #: doc/tutorial-borrowed-ptr.md:134
236 "~~~ # struct Point {x: float, y: float} let tmp = Point {x: 3.0, y: 4.0}; "
237 "let on_the_stack2 : &Point = &tmp; ~~~"
241 #: doc/tutorial-borrowed-ptr.md:136
242 msgid "# Taking the address of fields"
246 #: doc/tutorial-borrowed-ptr.md:141
248 "As in C, the `&` operator is not limited to taking the address of local "
249 "variables. It can also take the address of fields or individual array "
250 "elements. For example, consider this type definition for `rectangle`:"
254 #: doc/tutorial-borrowed-ptr.md:147
256 "~~~ struct Point {x: float, y: float} // as before struct Size {w: float, h: "
257 "float} // as before struct Rectangle {origin: Point, size: Size} ~~~"
261 #: doc/tutorial-borrowed-ptr.md:149
262 msgid "Now, as before, we can define rectangles in a few different ways:"
266 #: doc/tutorial-borrowed-ptr.md:161
270 "# struct Point {x: float, y: float}\n"
271 "# struct Size {w: float, h: float} // as before\n"
272 "# struct Rectangle {origin: Point, size: Size}\n"
273 "let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f},\n"
274 " size: Size {w: 3f, h: 4f}};\n"
275 "let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f},\n"
276 " size: Size {w: 3f, h: 4f}};\n"
277 "let rect_owned = ~Rectangle {origin: Point {x: 5f, y: 6f},\n"
278 " size: Size {w: 3f, h: 4f}};\n"
283 #: doc/tutorial-borrowed-ptr.md:164
285 "In each case, we can extract out individual subcomponents with the `&` "
286 "operator. For example, I could write:"
290 #: doc/tutorial-borrowed-ptr.md:175
292 "~~~ # struct Point {x: float, y: float} // as before # struct Size {w: "
293 "float, h: float} // as before # struct Rectangle {origin: Point, size: Size} "
294 "# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: "
295 "3f, h: 4f}}; # let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, "
296 "size: Size {w: 3f, h: 4f}}; # let rect_owned = ~Rectangle {origin: Point {x: "
297 "5f, y: 6f}, size: Size {w: 3f, h: 4f}}; # fn compute_distance(p1: &Point, "
298 "p2: &Point) -> float { 0f } compute_distance(&rect_stack.origin, "
299 "&rect_managed.origin); ~~~"
303 #: doc/tutorial-borrowed-ptr.md:178
305 "which would borrow the field `origin` from the rectangle on the stack as "
306 "well as from the managed box, and then compute the distance between them."
310 #: doc/tutorial-borrowed-ptr.md:180
311 msgid "# Borrowing managed boxes and rooting"
315 #: doc/tutorial-borrowed-ptr.md:186
317 "We’ve seen a few examples so far of borrowing heap boxes, both managed and "
318 "owned. Up till this point, we’ve glossed over issues of safety. As stated in "
319 "the introduction, at runtime a borrowed pointer is simply a pointer, nothing "
320 "more. Therefore, avoiding C's problems with dangling pointers requires a "
321 "compile-time safety check."
325 #: doc/tutorial-borrowed-ptr.md:197
327 "The basis for the check is the notion of _lifetimes_. A lifetime is a static "
328 "approximation of the span of execution during which the pointer is valid: it "
329 "always corresponds to some expression or block within the program. Code "
330 "inside that expression can use the pointer without restrictions. But if the "
331 "pointer escapes from that expression (for example, if the expression "
332 "contains an assignment expression that assigns the pointer to a mutable "
333 "field of a data structure with a broader scope than the pointer itself), the "
334 "compiler reports an error. We'll be discussing lifetimes more in the "
335 "examples to come, and a more thorough introduction is also available."
339 #: doc/tutorial-borrowed-ptr.md:202
341 "When the `&` operator creates a borrowed pointer, the compiler must ensure "
342 "that the pointer remains valid for its entire lifetime. Sometimes this is "
343 "relatively easy, such as when taking the address of a local variable or a "
344 "field that is stored on the stack:"
348 #: doc/tutorial-borrowed-ptr.md:211
352 "struct X { f: int }\n"
354 " let mut x = X { f: 3 };\n"
355 " let y = &mut x.f; // -+ L\n"
362 #: doc/tutorial-borrowed-ptr.md:216
364 "Here, the lifetime of the borrowed pointer `y` is simply L, the remainder of "
365 "the function body. The compiler need not do any other work to prove that "
366 "code will not free `x.f`. This is true even if the code mutates `x`."
370 #: doc/tutorial-borrowed-ptr.md:218
371 msgid "The situation gets more complex when borrowing data inside heap boxes:"
375 #: doc/tutorial-borrowed-ptr.md:227
379 "# struct X { f: int }\n"
381 " let mut x = @X { f: 3 };\n"
382 " let y = &x.f; // -+ L\n"
389 #: doc/tutorial-borrowed-ptr.md:238
391 "In this example, the value `x` is a heap box, and `y` is therefore a pointer "
392 "into that heap box. Again the lifetime of `y` is L, the remainder of the "
393 "function body. But there is a crucial difference: suppose `x` were to be "
394 "reassigned during the lifetime L? If the compiler isn't careful, the managed "
395 "box could become *unrooted*, and would therefore be subject to garbage "
396 "collection. A heap box that is unrooted is one such that no pointer values "
397 "in the heap point to it. It would violate memory safety for the box that was "
398 "originally assigned to `x` to be garbage-collected, since a non-heap pointer "
399 "*`y`* still points into it."
403 #: doc/tutorial-borrowed-ptr.md:241
405 "> ***Note:*** Our current implementation implements the garbage collector > "
406 "using reference counting and cycle detection."
410 #: doc/tutorial-borrowed-ptr.md:247
412 "For this reason, whenever an `&` expression borrows the interior of a "
413 "managed box stored in a mutable location, the compiler inserts a temporary "
414 "that ensures that the managed box remains live for the entire lifetime. So, "
415 "the above example would be compiled as if it were written"
419 #: doc/tutorial-borrowed-ptr.md:257
423 "# struct X { f: int }\n"
425 " let mut x = @X {f: 3};\n"
427 " let y = &x1.f; // -+ L\n"
434 #: doc/tutorial-borrowed-ptr.md:260
436 "Now if `x` is reassigned, the pointer `y` will still remain valid. This "
437 "process is called *rooting*."
441 #: doc/tutorial-borrowed-ptr.md:262
442 msgid "# Borrowing owned boxes"
446 #: doc/tutorial-borrowed-ptr.md:268
448 "The previous example demonstrated *rooting*, the process by which the "
449 "compiler ensures that managed boxes remain live for the duration of a "
450 "borrow. Unfortunately, rooting does not work for borrows of owned boxes, "
451 "because it is not possible to have two references to a owned box."
455 #: doc/tutorial-borrowed-ptr.md:274
457 "For owned boxes, therefore, the compiler will only allow a borrow *if the "
458 "compiler can guarantee that the owned box will not be reassigned or moved "
459 "for the lifetime of the pointer*. This does not necessarily mean that the "
460 "owned box is stored in immutable memory. For example, the following function "
465 #: doc/tutorial-borrowed-ptr.md:289
469 "# fn some_condition() -> bool { true }\n"
470 "# struct Foo { f: int }\n"
471 "fn example3() -> int {\n"
472 " let mut x = ~Foo {f: 3};\n"
473 " if some_condition() {\n"
474 " let y = &x.f; // -+ L\n"
477 " x = ~Foo {f: 4};\n"
485 #: doc/tutorial-borrowed-ptr.md:295
487 "Here, as before, the interior of the variable `x` is being borrowed and `x` "
488 "is declared as mutable. However, the compiler can prove that `x` is not "
489 "assigned anywhere in the lifetime L of the variable `y`. Therefore, it "
490 "accepts the function, even though `x` is mutable and in fact is mutated "
491 "later in the function."
495 #: doc/tutorial-borrowed-ptr.md:301
497 "It may not be clear why we are so concerned about mutating a borrowed "
498 "variable. The reason is that the runtime system frees any owned box _as soon "
499 "as its owning reference changes or goes out of scope_. Therefore, a program "
500 "like this is illegal (and would be rejected by the compiler):"
504 #: doc/tutorial-borrowed-ptr.md:310
507 "~~~ {.xfail-test}\n"
508 "fn example3() -> int {\n"
509 " let mut x = ~X {f: 3};\n"
511 " x = ~X {f: 4}; // Error reported here.\n"
518 #: doc/tutorial-borrowed-ptr.md:313
520 "To make this clearer, consider this diagram showing the state of memory "
521 "immediately before the re-assignment of `x`:"
525 #: doc/tutorial-borrowed-ptr.md:316 doc/tutorial-borrowed-ptr.md:330
529 " Stack Exchange Heap\n"
533 #: doc/tutorial-borrowed-ptr.md:325
537 " | ~{f:int} | ----+\n"
538 " y +----------+ |\n"
540 " +----------+ | +---------+\n"
547 #: doc/tutorial-borrowed-ptr.md:327
548 msgid "Once the reassignment occurs, the memory will look like this:"
552 #: doc/tutorial-borrowed-ptr.md:339
555 " x +----------+ +---------+\n"
556 " | ~{f:int} | -------> | f: 4 |\n"
557 " y +----------+ +---------+\n"
559 " +----------+ | +---------+\n"
560 " +--> | (freed) |\n"
566 #: doc/tutorial-borrowed-ptr.md:342
568 "Here you can see that the variable `y` still points at the old box, which "
573 #: doc/tutorial-borrowed-ptr.md:348
575 "In fact, the compiler can apply the same kind of reasoning to any memory "
576 "that is _(uniquely) owned by the stack frame_. So we could modify the "
577 "previous example to introduce additional owned pointers and structs, and the "
578 "compiler will still be able to detect possible mutations:"
582 #: doc/tutorial-borrowed-ptr.md:353
585 "~~~ {.xfail-test}\n"
586 "fn example3() -> int {\n"
587 " struct R { g: int }\n"
588 " struct S { f: ~R }\n"
592 #: doc/tutorial-borrowed-ptr.md:361
595 " let mut x = ~S {f: ~R {g: 3}};\n"
597 " x = ~S {f: ~R {g: 4}}; // Error reported here.\n"
598 " x.f = ~R {g: 5}; // Error reported here.\n"
605 #: doc/tutorial-borrowed-ptr.md:365
607 "In this case, two errors are reported, one when the variable `x` is modified "
608 "and another when `x.f` is modified. Either modification would invalidate the "
613 #: doc/tutorial-borrowed-ptr.md:367
614 msgid "# Borrowing and enums"
618 #: doc/tutorial-borrowed-ptr.md:373
620 "The previous example showed that the type system forbids any borrowing of "
621 "owned boxes found in aliasable, mutable memory. This restriction prevents "
622 "pointers from pointing into freed memory. There is one other case where the "
623 "compiler must be very careful to ensure that pointers remain valid: pointers "
624 "into the interior of an `enum`."
628 #: doc/tutorial-borrowed-ptr.md:376
630 "As an example, let’s look at the following `shape` type that can represent "
631 "both rectangles and circles:"
635 #: doc/tutorial-borrowed-ptr.md:385
639 "struct Point {x: float, y: float}; // as before\n"
640 "struct Size {w: float, h: float}; // as before\n"
642 " Circle(Point, float), // origin, radius\n"
643 " Rectangle(Point, Size) // upper-left, dimensions\n"
649 #: doc/tutorial-borrowed-ptr.md:389
651 "Now we might write a function to compute the area of a shape. This function "
652 "takes a borrowed pointer to a shape, to avoid the need for copying."
656 #: doc/tutorial-borrowed-ptr.md:405
660 "# struct Point {x: float, y: float}; // as before\n"
661 "# struct Size {w: float, h: float}; // as before\n"
663 "# Circle(Point, float), // origin, radius\n"
664 "# Rectangle(Point, Size) // upper-left, dimensions\n"
666 "# static tau: float = 6.28f;\n"
667 "fn compute_area(shape: &Shape) -> float {\n"
669 " Circle(_, radius) => 0.5 * tau * radius * radius,\n"
670 " Rectangle(_, ref size) => size.w * size.h\n"
677 #: doc/tutorial-borrowed-ptr.md:410
679 "The first case matches against circles. Here, the pattern extracts the "
680 "radius from the shape variant and the action uses it to compute the area of "
681 "the circle. (Like any up-to-date engineer, we use the [tau circle constant]"
682 "[tau] and not that dreadfully outdated notion of pi)."
686 #: doc/tutorial-borrowed-ptr.md:412
687 msgid "[tau]: http://www.math.utah.edu/~palais/pi.html"
691 #: doc/tutorial-borrowed-ptr.md:418
693 "The second match is more interesting. Here we match against a rectangle and "
694 "extract its size: but rather than copy the `size` struct, we use a by-"
695 "reference binding to create a pointer to it. In other words, a pattern "
696 "binding like `ref size` binds the name `size` to a pointer of type `&size` "
697 "into the _interior of the enum_."
701 #: doc/tutorial-borrowed-ptr.md:421
703 "To make this more clear, let's look at a diagram of memory layout in the "
704 "case where `shape` points at a rectangle:"
708 #: doc/tutorial-borrowed-ptr.md:424 doc/tutorial-borrowed-ptr.md:449
716 #: doc/tutorial-borrowed-ptr.md:433
719 "+-------+ +---------------+\n"
720 "| shape | ------> | rectangle( |\n"
721 "+-------+ | {x: float, |\n"
722 "| size | -+ | y: float}, |\n"
723 "+-------+ +----> | {w: float, |\n"
725 " +---------------+\n"
730 #: doc/tutorial-borrowed-ptr.md:440
732 "Here you can see that rectangular shapes are composed of five words of "
733 "memory. The first is a tag indicating which variant this enum is "
734 "(`rectangle`, in this case). The next two words are the `x` and `y` fields "
735 "for the point and the remaining two are the `w` and `h` fields for the size. "
736 "The binding `size` is then a pointer into the inside of the shape."
740 #: doc/tutorial-borrowed-ptr.md:446
742 "Perhaps you can see where the danger lies: if the shape were somehow to be "
743 "reassigned, perhaps to a circle, then although the memory used to store that "
744 "shape value would still be valid, _it would have a different type_! The "
745 "following diagram shows what memory would look like if code overwrote "
746 "`shape` with a circle:"
750 #: doc/tutorial-borrowed-ptr.md:458
753 "+-------+ +---------------+\n"
754 "| shape | ------> | circle( |\n"
755 "+-------+ | {x: float, |\n"
756 "| size | -+ | y: float}, |\n"
757 "+-------+ +----> | float) |\n"
759 " +---------------+\n"
764 #: doc/tutorial-borrowed-ptr.md:463
766 "As you can see, the `size` pointer would be pointing at a `float` instead of "
767 "a struct. This is not good: dereferencing the second field of a `float` as "
768 "if it were a struct with two fields would be a memory safety violation."
772 #: doc/tutorial-borrowed-ptr.md:475
774 "So, in fact, for every `ref` binding, the compiler will impose the same "
775 "rules as the ones we saw for borrowing the interior of a owned box: it must "
776 "be able to guarantee that the `enum` will not be overwritten for the "
777 "duration of the borrow. In fact, the compiler would accept the example we "
778 "gave earlier. The example is safe because the shape pointer has type "
779 "`&Shape`, which means \"borrowed pointer to immutable memory containing a "
780 "`shape`\". If, however, the type of that pointer were `&mut Shape`, then the "
781 "ref binding would be ill-typed. Just as with owned boxes, the compiler will "
782 "permit `ref` bindings into data owned by the stack frame even if the data "
783 "are mutable, but otherwise it requires that the data reside in immutable "
788 #: doc/tutorial-borrowed-ptr.md:477
789 msgid "# Returning borrowed pointers"
793 #: doc/tutorial-borrowed-ptr.md:483
795 "So far, all of the examples we have looked at, use borrowed pointers in a "
796 "“downward” direction. That is, a method or code block creates a borrowed "
797 "pointer, then uses it within the same scope. It is also possible to return "
798 "borrowed pointers as the result of a function, but as we'll see, doing so "
799 "requires some explicit annotation."
803 #: doc/tutorial-borrowed-ptr.md:485
804 msgid "For example, we could write a subroutine like this:"
808 #: doc/tutorial-borrowed-ptr.md:490
810 "~~~ struct Point {x: float, y: float} fn get_x<'r>(p: &'r Point) -> &'r "
815 #: doc/tutorial-borrowed-ptr.md:498
817 "Here, the function `get_x()` returns a pointer into the structure it was "
818 "given. The type of the parameter (`&'r Point`) and return type (`&'r float`) "
819 "both use a new syntactic form that we have not seen so far. Here the "
820 "identifier `r` names the lifetime of the pointer explicitly. So in effect, "
821 "this function declares that it takes a pointer with lifetime `r` and returns "
822 "a pointer with that same lifetime."
826 #: doc/tutorial-borrowed-ptr.md:504
828 "In general, it is only possible to return borrowed pointers if they are "
829 "derived from a parameter to the procedure. In that case, the pointer result "
830 "will always have the same lifetime as one of the parameters; named lifetimes "
831 "indicate which parameter that is."
835 #: doc/tutorial-borrowed-ptr.md:510
837 "In the previous examples, function parameter types did not include a "
838 "lifetime name. In those examples, the compiler simply creates a fresh name "
839 "for the lifetime automatically: that is, the lifetime name is guaranteed to "
840 "refer to a distinct lifetime from the lifetimes of all other parameters."
844 #: doc/tutorial-borrowed-ptr.md:518
846 "Named lifetimes that appear in function signatures are conceptually the same "
847 "as the other lifetimes we have seen before, but they are a bit abstract: "
848 "they don’t refer to a specific expression within `get_x()`, but rather to "
849 "some expression within the *caller of `get_x()`*. The lifetime `r` is "
850 "actually a kind of *lifetime parameter*: it is defined by the caller to "
851 "`get_x()`, just as the value for the parameter `p` is defined by that caller."
855 #: doc/tutorial-borrowed-ptr.md:523
857 "In any case, whatever the lifetime of `r` is, the pointer produced by `&p.x` "
858 "always has the same lifetime as `p` itself: a pointer to a field of a struct "
859 "is valid as long as the struct is valid. Therefore, the compiler accepts the "
860 "function `get_x()`."
864 #: doc/tutorial-borrowed-ptr.md:526
866 "To emphasize this point, let’s look at a variation on the example, this time "
867 "one that does not compile:"
871 #: doc/tutorial-borrowed-ptr.md:533
874 "~~~ {.xfail-test}\n"
875 "struct Point {x: float, y: float}\n"
876 "fn get_x_sh(p: @Point) -> &float {\n"
877 " &p.x // Error reported here\n"
883 #: doc/tutorial-borrowed-ptr.md:541
885 "Here, the function `get_x_sh()` takes a managed box as input and returns a "
886 "borrowed pointer. As before, the lifetime of the borrowed pointer that will "
887 "be returned is a parameter (specified by the caller). That means that "
888 "`get_x_sh()` promises to return a borrowed pointer that is valid for as long "
889 "as the caller would like: this is subtly different from the first example, "
890 "which promised to return a pointer that was valid for as long as its pointer "
891 "argument was valid."
895 #: doc/tutorial-borrowed-ptr.md:552
897 "Within `get_x_sh()`, we see the expression `&p.x` which takes the address of "
898 "a field of a managed box. The presence of this expression implies that the "
899 "compiler must guarantee that, so long as the resulting pointer is valid, the "
900 "managed box will not be reclaimed by the garbage collector. But recall that "
901 "`get_x_sh()` also promised to return a pointer that was valid for as long as "
902 "the caller wanted it to be. Clearly, `get_x_sh()` is not in a position to "
903 "make both of these guarantees; in fact, it cannot guarantee that the pointer "
904 "will remain valid at all once it returns, as the parameter `p` may or may "
905 "not be live in the caller. Therefore, the compiler will report an error here."
909 #: doc/tutorial-borrowed-ptr.md:559
911 "In general, if you borrow a managed (or owned) box to create a borrowed "
912 "pointer, the pointer will only be valid within the function and cannot be "
913 "returned. This is why the typical way to return borrowed pointers is to take "
914 "borrowed pointers as input (the only other case in which it can be legal to "
915 "return a borrowed pointer is if the pointer points at a static constant)."
919 #: doc/tutorial-borrowed-ptr.md:561
920 msgid "# Named lifetimes"
924 #: doc/tutorial-borrowed-ptr.md:565
926 "Let's look at named lifetimes in more detail. Named lifetimes allow for "
927 "grouping of parameters by lifetime. For example, consider this function:"
931 #: doc/tutorial-borrowed-ptr.md:579
935 "# struct Point {x: float, y: float}; // as before\n"
936 "# struct Size {w: float, h: float}; // as before\n"
938 "# Circle(Point, float), // origin, radius\n"
939 "# Rectangle(Point, Size) // upper-left, dimensions\n"
941 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
942 "fn select<'r, T>(shape: &'r Shape, threshold: float,\n"
943 " a: &'r T, b: &'r T) -> &'r T {\n"
944 " if compute_area(shape) > threshold {a} else {b}\n"
950 #: doc/tutorial-borrowed-ptr.md:585
952 "This function takes three borrowed pointers and assigns each the same "
953 "lifetime `r`. In practice, this means that, in the caller, the lifetime `r` "
954 "will be the *intersection of the lifetime of the three region parameters*. "
955 "This may be overly conservative, as in this example:"
959 #: doc/tutorial-borrowed-ptr.md:607
963 "# struct Point {x: float, y: float}; // as before\n"
964 "# struct Size {w: float, h: float}; // as before\n"
966 "# Circle(Point, float), // origin, radius\n"
967 "# Rectangle(Point, Size) // upper-left, dimensions\n"
969 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
970 "# fn select<'r, T>(shape: &Shape, threshold: float,\n"
971 "# a: &'r T, b: &'r T) -> &'r T {\n"
972 "# if compute_area(shape) > threshold {a} else {b}\n"
975 "fn select_based_on_unit_circle<'r, T>( // |-+ B\n"
976 " threshold: float, a: &'r T, b: &'r T) -> &'r T { // | |\n"
978 " let shape = Circle(Point {x: 0., y: 0.}, 1.); // | |\n"
979 " select(&shape, threshold, a, b) // | |\n"
986 #: doc/tutorial-borrowed-ptr.md:617
988 "In this call to `select()`, the lifetime of the first parameter shape is B, "
989 "the function body. Both of the second two parameters `a` and `b` share the "
990 "same lifetime, `r`, which is a lifetime parameter of "
991 "`select_based_on_unit_circle()`. The caller will infer the intersection of "
992 "these two lifetimes as the lifetime of the returned value, and hence the "
993 "return value of `select()` will be assigned a lifetime of B. This will in "
994 "turn lead to a compilation error, because `select_based_on_unit_circle()` is "
995 "supposed to return a value with the lifetime `r`."
999 #: doc/tutorial-borrowed-ptr.md:622
1001 "To address this, we can modify the definition of `select()` to distinguish "
1002 "the lifetime of the first parameter from the lifetime of the latter two. "
1003 "After all, the first parameter is not being returned. Here is how the new "
1004 "`select()` might look:"
1008 #: doc/tutorial-borrowed-ptr.md:636
1012 "# struct Point {x: float, y: float}; // as before\n"
1013 "# struct Size {w: float, h: float}; // as before\n"
1015 "# Circle(Point, float), // origin, radius\n"
1016 "# Rectangle(Point, Size) // upper-left, dimensions\n"
1018 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
1019 "fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: float,\n"
1020 " a: &'r T, b: &'r T) -> &'r T {\n"
1021 " if compute_area(shape) > threshold {a} else {b}\n"
1027 #: doc/tutorial-borrowed-ptr.md:641
1029 "Here you can see that `shape`'s lifetime is now named `tmp`. The parameters "
1030 "`a`, `b`, and the return value all have the lifetime `r`. However, since "
1031 "the lifetime `tmp` is not returned, it would be more concise to just omit "
1032 "the named lifetime for `shape` altogether:"
1036 #: doc/tutorial-borrowed-ptr.md:655
1040 "# struct Point {x: float, y: float}; // as before\n"
1041 "# struct Size {w: float, h: float}; // as before\n"
1043 "# Circle(Point, float), // origin, radius\n"
1044 "# Rectangle(Point, Size) // upper-left, dimensions\n"
1046 "# fn compute_area(shape: &Shape) -> float { 0f }\n"
1047 "fn select<'r, T>(shape: &Shape, threshold: float,\n"
1048 " a: &'r T, b: &'r T) -> &'r T {\n"
1049 " if compute_area(shape) > threshold {a} else {b}\n"
1055 #: doc/tutorial-borrowed-ptr.md:657
1056 msgid "This is equivalent to the previous definition."
1060 #: doc/tutorial-borrowed-ptr.md:659
1061 msgid "# Conclusion"
1065 #: doc/tutorial-borrowed-ptr.md:663
1067 "So there you have it: a (relatively) brief tour of the borrowed pointer "
1068 "system. For more details, we refer to the (yet to be written) reference "
1069 "document on borrowed pointers, which will explain the full notation and give "