From 7dfa4b298262fde037b5fbbb8fe20468d7306cbb Mon Sep 17 00:00:00 2001 From: noam Date: Sun, 23 Mar 2014 16:05:01 -0400 Subject: [PATCH 1/2] docs: named lifetimes * Include tip given by Leo Testard in mailing list about labeled `break` and `continue`: https://mail.mozilla.org/pipermail/rust-dev/2014-March/009145.html * cross-reference named lifetimes in tutorial -> lifetimes guide * Broke named lifetimes section into two sub-sections. * Added mention of `'static` lifetime. --- src/doc/guide-lifetimes.md | 25 ++++++++++++++++++++++--- src/doc/tutorial.md | 3 ++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/doc/guide-lifetimes.md b/src/doc/guide-lifetimes.md index 69596b6e304..20268ce8bbe 100644 --- a/src/doc/guide-lifetimes.md +++ b/src/doc/guide-lifetimes.md @@ -559,9 +559,14 @@ points at a static constant). # Named lifetimes -Let's look at named lifetimes in more detail. Named lifetimes allow -for grouping of parameters by lifetime. For example, consider this -function: +Lifetimes can be named and referenced. For example, the special lifetime +`'static`, which does not go out of scope, can be used to create global +variables and communicate between tasks (see the manual for usecases). + +## Parameter Lifetimes + +Named lifetimes allow for grouping of parameters by lifetime. +For example, consider this function: ~~~ # struct Point {x: f64, y: f64}; // as before @@ -655,6 +660,20 @@ fn select<'r, T>(shape: &Shape, threshold: f64, This is equivalent to the previous definition. +## Labeled Control Structures + +Named lifetime notation can also be used to control the flow of execution: + +~~~ +'h: for i in range(0,10) { + 'g: loop { + if i % 2 == 0 { continue 'h; } + if i == 9 { break 'h; } + break 'g; + } +} +~~~ + # Conclusion So there you have it: a (relatively) brief tour of the lifetime diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index bfa1a3a2a29..09539e6d59d 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -2103,7 +2103,8 @@ a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal muta These are types that do not contain any data whose lifetime is bound to a particular stack frame. These are types that do not contain any references, or types where the only contained references -have the `'static` lifetime. +have the `'static` lifetime. (For more on named lifetimes and their uses, +see the [references and lifetimes guide][lifetimes].) > ***Note:*** These two traits were referred to as 'kinds' in earlier > iterations of the language, and often still are. From 4b224af72a76770694dc0998b356d9ce4d77529b Mon Sep 17 00:00:00 2001 From: noam Date: Sun, 23 Mar 2014 21:24:17 -0400 Subject: [PATCH 2/2] Added suggested notes * Note on while loop not supporting named breaks. * Note on hygienic macros (and example of such within loops) --- src/doc/guide-lifetimes.md | 9 +++++++-- src/doc/guide-macros.md | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/doc/guide-lifetimes.md b/src/doc/guide-lifetimes.md index 20268ce8bbe..eb16f73c3a9 100644 --- a/src/doc/guide-lifetimes.md +++ b/src/doc/guide-lifetimes.md @@ -559,13 +559,13 @@ points at a static constant). # Named lifetimes -Lifetimes can be named and referenced. For example, the special lifetime +Lifetimes can be named and referenced. For example, the special lifetime `'static`, which does not go out of scope, can be used to create global variables and communicate between tasks (see the manual for usecases). ## Parameter Lifetimes -Named lifetimes allow for grouping of parameters by lifetime. +Named lifetimes allow for grouping of parameters by lifetime. For example, consider this function: ~~~ @@ -674,6 +674,11 @@ Named lifetime notation can also be used to control the flow of execution: } ~~~ +> ***Note:*** Labelled breaks are not currently supported within `while` loops. + +Named labels are hygienic and can be used safely within macros. +See the macros guide section on hygiene for more details. + # Conclusion So there you have it: a (relatively) brief tour of the lifetime diff --git a/src/doc/guide-macros.md b/src/doc/guide-macros.md index 527777a0eba..23510997f24 100644 --- a/src/doc/guide-macros.md +++ b/src/doc/guide-macros.md @@ -398,6 +398,38 @@ position (in particular, not as an argument to yet another macro invocation), the expander will then proceed to evaluate `m2!()` (along with any other macro invocations `m1!(m2!())` produced). +# Hygiene + +To prevent clashes, rust implements +[hygienic macros](http://en.wikipedia.org/wiki/Hygienic_macro). + +As an example, `loop` and `for-loop` labels (discussed in the lifetimes guide) +will not clash. The following code will print "Hello!" only once: + +~~~ +#[feature(macro_rules)]; + +macro_rules! loop_x ( + ($e: expr) => ( + // $e will not interact with this 'x + 'x: loop { + println!("Hello!"); + $e + } + ); +) + +fn main() { + 'x: loop { + loop_x!(break 'x); + println!("I am never printed."); + } +} +~~~ + +The two `'x` names did not clash, which would have caused the loop +to print "I am never printed" and to run forever. + # A final note Macros, as currently implemented, are not for the faint of heart. Even