From 47ebc48140f45f93057ad764e34f1f2223ece5aa Mon Sep 17 00:00:00 2001 From: Raphael Speyer Date: Tue, 21 Apr 2015 02:01:06 +1000 Subject: [PATCH 01/16] Implement IntoIterator for Receiver --- src/libstd/sync/mpsc/mod.rs | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 422439fadc1a1..b3cc133d22946 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -306,6 +306,14 @@ pub struct Iter<'a, T: 'a> { rx: &'a Receiver } +/// An owning iterator over messages on a receiver, this iterator will block +/// whenever `next` is called, waiting for a new message, and `None` will be +/// returned when the corresponding channel has hung up. +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +pub struct IntoIter { + rx: Receiver +} + /// The sending-half of Rust's asynchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. #[stable(feature = "rust1", since = "1.0.0")] @@ -899,6 +907,29 @@ impl<'a, T> Iterator for Iter<'a, T> { fn next(&mut self) -> Option { self.rx.recv().ok() } } +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +impl<'a, T> IntoIterator for &'a Receiver { + type Item = T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Iter<'a, T> { self.iter() } +} + +impl Iterator for IntoIter { + type Item = T; + fn next(&mut self) -> Option { self.rx.recv().ok() } +} + +#[stable(feature = "receiver_into_iter", since = "1.1.0")] +impl IntoIterator for Receiver { + type Item = T; + type IntoIter = IntoIter; + + fn into_iter(self) -> IntoIter { + IntoIter { rx: self } + } +} + #[unsafe_destructor] #[stable(feature = "rust1", since = "1.0.0")] impl Drop for Receiver { @@ -1507,6 +1538,32 @@ mod test { assert_eq!(count_rx.recv().unwrap(), 4); } + #[test] + fn test_recv_into_iter_owned() { + let mut iter = { + let (tx, rx) = channel::(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + + rx.into_iter() + }; + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); + } + + #[test] + fn test_recv_into_iter_borrowed() { + let (tx, rx) = channel::(); + tx.send(1).unwrap(); + tx.send(2).unwrap(); + drop(tx); + let mut iter = (&rx).into_iter(); + assert_eq!(iter.next().unwrap(), 1); + assert_eq!(iter.next().unwrap(), 2); + assert_eq!(iter.next().is_none(), true); + } + #[test] fn try_recv_states() { let (tx1, rx1) = channel::(); From efb457b8cf121b788728967b04cd2121c53167dd Mon Sep 17 00:00:00 2001 From: nwin Date: Thu, 23 Apr 2015 21:23:35 +0200 Subject: [PATCH 02/16] object type -> trait object Consistency. The book also refers to it as trait objects. --- src/doc/reference.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..a43fca7c19d6f 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1555,7 +1555,7 @@ fn draw_twice(surface: Surface, sh: T) { } ``` -Traits also define an [object type](#object-types) with the same name as the +Traits also define an [trait object](#trait-objects) with the same name as the trait. Values of this type are created by [casting](#type-cast-expressions) pointer values (pointing to a type for which an implementation of the given trait is in scope) to pointers to the trait name, used as a type. @@ -2744,7 +2744,7 @@ A _method call_ consists of an expression followed by a single dot, an identifier, and a parenthesized expression-list. Method calls are resolved to methods on specific traits, either statically dispatching to a method if the exact `self`-type of the left-hand-side is known, or dynamically dispatching if -the left-hand-side expression is an indirect [object type](#object-types). +the left-hand-side expression is an indirect [trait object](#trait-objects). ### Field expressions @@ -3649,23 +3649,23 @@ call_closure(closure_no_args, closure_args); ``` -### Object types +### Trait objects Every trait item (see [traits](#traits)) defines a type with the same name as -the trait. This type is called the _object type_ of the trait. Object types +the trait. This type is called the _trait object_ of the trait. Trait objects permit "late binding" of methods, dispatched using _virtual method tables_ ("vtables"). Whereas most calls to trait methods are "early bound" (statically resolved) to specific implementations at compile time, a call to a method on an -object type is only resolved to a vtable entry at compile time. The actual +trait objects is only resolved to a vtable entry at compile time. The actual implementation for each vtable entry can vary on an object-by-object basis. Given a pointer-typed expression `E` of type `&T` or `Box`, where `T` implements trait `R`, casting `E` to the corresponding pointer type `&R` or -`Box` results in a value of the _object type_ `R`. This result is +`Box` results in a value of the _trait object_ `R`. This result is represented as a pair of pointers: the vtable pointer for the `T` implementation of `R`, and the pointer value of `E`. -An example of an object type: +An example of an trait object: ``` trait Printable { @@ -3685,7 +3685,7 @@ fn main() { } ``` -In this example, the trait `Printable` occurs as an object type in both the +In this example, the trait `Printable` occurs as an trait object in both the type signature of `print`, and the cast expression in `main`. ### Type parameters From a8f5989afbd32d76f65847e64f947851d3fc0059 Mon Sep 17 00:00:00 2001 From: nwin Date: Thu, 23 Apr 2015 21:25:09 +0200 Subject: [PATCH 03/16] typo --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index a43fca7c19d6f..1b8525dde8cc5 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3665,7 +3665,7 @@ implements trait `R`, casting `E` to the corresponding pointer type `&R` or represented as a pair of pointers: the vtable pointer for the `T` implementation of `R`, and the pointer value of `E`. -An example of an trait object: +An example of a trait object: ``` trait Printable { From 99fd7f213183bcf421ac881663ef2913ac4466b4 Mon Sep 17 00:00:00 2001 From: nwin Date: Thu, 23 Apr 2015 21:26:34 +0200 Subject: [PATCH 04/16] typo 2 --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 1b8525dde8cc5..af6db58c7e03a 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3685,7 +3685,7 @@ fn main() { } ``` -In this example, the trait `Printable` occurs as an trait object in both the +In this example, the trait `Printable` occurs as a trait object in both the type signature of `print`, and the cast expression in `main`. ### Type parameters From 58b3b8bcfa0546cf571906df48185b7bfcf249b9 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Thu, 23 Apr 2015 12:32:25 -0700 Subject: [PATCH 05/16] Update supported values of target_os 'win32' -> 'windows', added 'ios' --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..debfe31d982d7 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2146,7 +2146,7 @@ The following configurations must be defined by the implementation: `"unix"` or `"windows"`. The value of this configuration option is defined as a configuration itself, like `unix` or `windows`. * `target_os = "..."`. Operating system of the target, examples include - `"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`, + `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`, `"bitrig"` or `"openbsd"`. * `target_pointer_width = "..."`. Target pointer width in bits. This is set to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for From 17934e5c29509fe72dbf6228033ab632919dba95 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 24 Apr 2015 08:45:32 +1200 Subject: [PATCH 06/16] Do not include attributes in trait item spans. (And other kinds of items). --- src/libsyntax/parse/parser.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dc577f603f621..68006a8979a64 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1151,8 +1151,8 @@ impl<'a> Parser<'a> { &token::CloseDelim(token::Brace), seq_sep_none(), |p| { - let lo = p.span.lo; let mut attrs = p.parse_outer_attributes(); + let lo = p.span.lo; let (name, node) = if try!(p.eat_keyword(keywords::Type)) { let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param()); @@ -3409,8 +3409,8 @@ impl<'a> Parser<'a> { } } - let lo = self.span.lo; let attrs = self.parse_outer_attributes(); + let lo = self.span.lo; Ok(Some(if self.check_keyword(keywords::Let) { check_expected_item(self, &attrs); @@ -4304,8 +4304,8 @@ impl<'a> Parser<'a> { /// Parse an impl item. pub fn parse_impl_item(&mut self) -> PResult> { - let lo = self.span.lo; let mut attrs = self.parse_outer_attributes(); + let lo = self.span.lo; let vis = try!(self.parse_visibility()); let (name, node) = if try!(self.eat_keyword(keywords::Type)) { let name = try!(self.parse_ident()); @@ -5380,9 +5380,8 @@ impl<'a> Parser<'a> { /// Parse a foreign item. fn parse_foreign_item(&mut self) -> PResult>> { - let lo = self.span.lo; - let attrs = self.parse_outer_attributes(); + let lo = self.span.lo; let visibility = try!(self.parse_visibility()); if self.check_keyword(keywords::Static) { From 1b878379e93491484a0c0e144e9b7ecf597e5ed6 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 23 Apr 2015 14:03:25 -0700 Subject: [PATCH 07/16] Clarify that //! comments are also doc comments. --- src/doc/reference.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..8a6f15a1ba4b2 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -149,9 +149,10 @@ sequence (`/**`), are interpreted as a special syntax for `doc` `#[doc="..."]` around the body of the comment (this includes the comment characters themselves, ie `/// Foo` turns into `#[doc="/// Foo"]`). -`//!` comments apply to the parent of the comment, rather than the item that -follows. `//!` comments are usually used to display information on the crate -index page. +Line comments beginning with `//!` are doc comments that apply to the parent +of the comment, rather than the item that follows. That is, they are +equivalent to writing `#![doc="..."]` around the body of the comment. `//!` +comments are usually used to display information on the crate index page. Non-doc comments are interpreted as a form of whitespace. From ad2684c41c9b30ead713c095b70e706ab056f07d Mon Sep 17 00:00:00 2001 From: Geoffrey Thomas Date: Thu, 23 Apr 2015 17:08:19 -0400 Subject: [PATCH 08/16] TRPL: Fix link to macro section of reference --- src/doc/trpl/macros.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index 9fa870ab1ac7c..f72abd24b9cfe 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -566,7 +566,7 @@ When this library is loaded with `#[macro_use] extern crate`, only `m2` will be imported. The Rust Reference has a [listing of macro-related -attributes](../reference.html#macro--and-plugin-related-attributes). +attributes](../reference.html#macro-related-attributes). # The variable `$crate` From 17390a1a79ce57c1d1e997821333a7e3b54ef158 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 23 Apr 2015 14:14:15 -0700 Subject: [PATCH 09/16] Update and organize the Keywords table * Add two missing keywords, `Self` and `proc` * Fix some mis-alphabetized keywords --- src/doc/reference.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..80ab69f0cf8b8 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -196,10 +196,11 @@ grammar as double-quoted strings. Other tokens have exact rules given. | fn | for | if | impl | in | | let | loop | macro | match | mod | | move | mut | offsetof | override | priv | -| pub | pure | ref | return | sizeof | -| static | self | struct | super | true | -| trait | type | typeof | unsafe | unsized | -| use | virtual | where | while | yield | +| proc | pub | pure | ref | return | +| Self | self | sizeof | static | struct | +| super | trait | true | type | typeof | +| unsafe | unsized | use | virtual | where | +| while | yield | | | | Each of these keywords has special meaning in its grammar, and all of them are From 2f491228c01eda39d08dd7da0e419ceae523012a Mon Sep 17 00:00:00 2001 From: Geoffrey Thomas Date: Thu, 23 Apr 2015 17:17:14 -0400 Subject: [PATCH 10/16] TRPL: Remove references to "advanced macros chapter" This was merged back into the regular macros chapter, but a few references lingered and caused broken links. --- src/doc/trpl/macros.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index f72abd24b9cfe..9d01f104ddaaf 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -57,8 +57,7 @@ let x: Vec = { We can implement this shorthand, using a macro: [^actual] [^actual]: The actual definition of `vec!` in libcollections differs from the - one presented here, for reasons of efficiency and reusability. Some - of these are mentioned in the [advanced macros chapter][]. + one presented here, for reasons of efficiency and reusability. ```rust macro_rules! vec { @@ -106,7 +105,7 @@ These have [their own little grammar] within the language. The matcher `$x:expr` will match any Rust expression, binding that syntax tree to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’; -the full possibilities are enumerated in the [advanced macros chapter][]. +the full possibilities are enumerated later in this chapter. Surrounding the matcher with `$(...),*` will match zero or more expressions, separated by commas. From 4cab21c00344eac1b8a6325c0d6254bc113022ad Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 23 Apr 2015 14:25:30 -0700 Subject: [PATCH 11/16] Also mention `/*!` doc comments. --- src/doc/reference.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 8a6f15a1ba4b2..44266fb40505e 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -149,10 +149,11 @@ sequence (`/**`), are interpreted as a special syntax for `doc` `#[doc="..."]` around the body of the comment (this includes the comment characters themselves, ie `/// Foo` turns into `#[doc="/// Foo"]`). -Line comments beginning with `//!` are doc comments that apply to the parent -of the comment, rather than the item that follows. That is, they are -equivalent to writing `#![doc="..."]` around the body of the comment. `//!` -comments are usually used to display information on the crate index page. +Line comments beginning with `//!` and block comments beginning with `/*!` are +doc comments that apply to the parent of the comment, rather than the item +that follows. That is, they are equivalent to writing `#![doc="..."]` around +the body of the comment. `//!` comments are usually used to display +information on the crate index page. Non-doc comments are interpreted as a form of whitespace. From da5f80cc6d56bec5d406e1c785c1f24fb2ab4103 Mon Sep 17 00:00:00 2001 From: Lee Aronson Date: Thu, 23 Apr 2015 16:46:33 -0700 Subject: [PATCH 12/16] Improve information about loops 1) Moved 'while' section below 'loop', 'break', and 'continue'; 2) Added information to 'while' and 'for' loops that they interact with 'break' and 'continue' and may have a lifetime label. 3) Clarified labeling syntax on the infinite loops. --- src/doc/reference.md | 69 +++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..0e00bf4f7994e 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3078,28 +3078,6 @@ fn ten_times(f: F) where F: Fn(i32) { ten_times(|j| println!("hello, {}", j)); ``` -### While loops - -```{.ebnf .gram} -while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ; -``` - -A `while` loop begins by evaluating the boolean loop conditional expression. -If the loop conditional expression evaluates to `true`, the loop body block -executes and control returns to the loop conditional expression. If the loop -conditional expression evaluates to `false`, the `while` expression completes. - -An example: - -``` -let mut i = 0; - -while i < 10 { - println!("hello"); - i = i + 1; -} -``` - ### Infinite loops A `loop` expression denotes an infinite loop. @@ -3108,10 +3086,11 @@ A `loop` expression denotes an infinite loop. loop_expr : [ lifetime ':' ] "loop" '{' block '}'; ``` -A `loop` expression may optionally have a _label_. If a label is present, then -labeled `break` and `continue` expressions nested within this loop may exit out -of this loop or return control to its head. See [Break -expressions](#break-expressions) and [Continue +A `loop` expression may optionally have a _label_. The label is written as +a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a +label is present, then labeled `break` and `continue` expressions nested +within this loop may exit out of this loop or return control to its head. +See [Break expressions](#break-expressions) and [Continue expressions](#continue-expressions). ### Break expressions @@ -3123,7 +3102,7 @@ break_expr : "break" [ lifetime ]; A `break` expression has an optional _label_. If the label is absent, then executing a `break` expression immediately terminates the innermost loop enclosing it. It is only permitted in the body of a loop. If the label is -present, then `break foo` terminates the loop with label `foo`, which need not +present, then `break 'foo` terminates the loop with label `'foo`, which need not be the innermost label enclosing the `break` expression, but must enclose it. ### Continue expressions @@ -3137,12 +3116,39 @@ executing a `continue` expression immediately terminates the current iteration of the innermost loop enclosing it, returning control to the loop *head*. In the case of a `while` loop, the head is the conditional expression controlling the loop. In the case of a `for` loop, the head is the call-expression -controlling the loop. If the label is present, then `continue foo` returns -control to the head of the loop with label `foo`, which need not be the +controlling the loop. If the label is present, then `continue 'foo` returns +control to the head of the loop with label `'foo`, which need not be the innermost label enclosing the `break` expression, but must enclose it. A `continue` expression is only permitted in the body of a loop. +### While loops + +```{.ebnf .gram} +while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ; +``` + +A `while` loop begins by evaluating the boolean loop conditional expression. +If the loop conditional expression evaluates to `true`, the loop body block +executes and control returns to the loop conditional expression. If the loop +conditional expression evaluates to `false`, the `while` expression completes. + +An example: + +``` +let mut i = 0; + +while i < 10 { + println!("hello"); + i = i + 1; +} +``` + +Like `loop` expressions, `while` loops can be controlled with `break` or +`continue`, and may optionally have a _label_. See [infinite +loops](#infinite-loops), [break expressions](#break-expressions), and +[continue expressions](#continue-expressions) for more information. + ### For expressions ```{.ebnf .gram} @@ -3177,6 +3183,11 @@ for i in 0..256 { } ``` +Like `loop` expressions, `while` loops can be controlled with `break` or +`continue`, and may optionally have a _label_. See [infinite +loops](#infinite-loops), [break expressions](#break-expressions), and +[continue expressions](#continue-expressions) for more information. + ### If expressions ```{.ebnf .gram} From 3ae6a5e48d63ac65670bf1f3adeadf59b5beb7dd Mon Sep 17 00:00:00 2001 From: Lee Aronson Date: Thu, 23 Apr 2015 16:50:05 -0700 Subject: [PATCH 13/16] Fixed typo --- src/doc/reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 0e00bf4f7994e..e04c4c3612f1b 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3183,7 +3183,7 @@ for i in 0..256 { } ``` -Like `loop` expressions, `while` loops can be controlled with `break` or +Like `loop` expressions, `for` loops can be controlled with `break` or `continue`, and may optionally have a _label_. See [infinite loops](#infinite-loops), [break expressions](#break-expressions), and [continue expressions](#continue-expressions) for more information. From 352838ed349d01ae16408221bc6a327bf3651ef2 Mon Sep 17 00:00:00 2001 From: Michael Rosenberg <42micro@gmail.com> Date: Thu, 23 Apr 2015 20:33:46 -0400 Subject: [PATCH 14/16] Update "Generic Functions" section Updated sample code to updated syntax (now compiles). Also tweaked the text to reflect the change. --- src/doc/reference.md | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..930cf44fd2ce9 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1099,40 +1099,31 @@ signature. Each type parameter must be explicitly declared, in an angle-bracket-enclosed, comma-separated list following the function name. ```{.ignore} -fn iter(seq: &[T], f: |T|) { - for elt in seq.iter() { f(elt); } +fn iter(seq: &[T], f: F) where T: Copy, F: Fn(T) { + for elt in seq { f(*elt); } } -fn map(seq: &[T], f: |T| -> U) -> Vec { +fn map(seq: &[T], f: F) -> Vec where T: Copy, U: Copy, F: Fn(T) -> U { let mut acc = vec![]; - for elt in seq.iter() { acc.push(f(elt)); } + for elt in seq { acc.push(f(*elt)); } acc } ``` Inside the function signature and body, the name of the type parameter can be -used as a type name. +used as a type name. [Trait](#traits) bounds can be specified for type parameters +to allow methods with that trait to be called on values of that type. This is +specified using the `where` syntax, as in the above example. When a generic function is referenced, its type is instantiated based on the context of the reference. For example, calling the `iter` function defined above on `[1, 2]` will instantiate type parameter `T` with `i32`, and require -the closure parameter to have type `fn(i32)`. +the closure parameter to have type `Fn(i32)`. The type parameters can also be explicitly supplied in a trailing [path](#paths) component after the function name. This might be necessary if there is not sufficient context to determine the type parameters. For example, `mem::size_of::() == 4`. -Since a parameter type is opaque to the generic function, the set of operations -that can be performed on it is limited. Values of parameter type can only be -moved, not copied. - -``` -fn id(x: T) -> T { x } -``` - -Similarly, [trait](#traits) bounds can be specified for type parameters to -allow methods with that trait to be called on values of that type. - #### Unsafety Unsafe operations are those that potentially violate the memory-safety From 4db0efb45c5b7686f88773b33aa42959f71109c9 Mon Sep 17 00:00:00 2001 From: tynopex Date: Thu, 23 Apr 2015 20:38:11 -0400 Subject: [PATCH 15/16] Update reference.md Add section for range expressions. --- src/doc/reference.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/doc/reference.md b/src/doc/reference.md index d918a320e63a9..b3a07bb6452ad 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2812,6 +2812,33 @@ _panicked state_. (["a", "b"])[10]; // panics ``` +### Range expressions + +```{.ebnf .gram} +range_expr : expr ".." expr | + expr ".." | + ".." expr | + ".." ; +``` + +The `..` operator will construct an object of one of the `std::ops::Range` variants. + +``` +1..2; // std::ops::Range +3..; // std::ops::RangeFrom +..4; // std::ops::RangeTo +..; // std::ops::RangeFull +``` + +The following expressions are equivalent. + +``` +let x = std::ops::Range {start: 0, end: 10}; +let y = 0..10; + +assert_eq!(x,y); +``` + ### Unary operator expressions Rust defines three unary operators. They are all written as prefix operators, From 131b5aca5a8c04f7a565e5f2c95eccbf9b75970f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 24 Apr 2015 10:38:07 +0530 Subject: [PATCH 16/16] fixup #24754 --- src/doc/reference.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 0157dc7b3676b..a61d635af7df9 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -700,9 +700,9 @@ in macro rules). In the transcriber, the designator is already known, and so only the name of a matched nonterminal comes after the dollar sign. In both the matcher and transcriber, the Kleene star-like operator indicates -repetition. The Kleene star operator consists of `$` and parenthesis, optionally +repetition. The Kleene star operator consists of `$` and parentheses, optionally followed by a separator token, followed by `*` or `+`. `*` means zero or more -repetitions, `+` means at least one repetition. The parenthesis are not matched or +repetitions, `+` means at least one repetition. The parentheses are not matched or transcribed. On the matcher side, a name is bound to _all_ of the names it matches, in a structure that mimics the structure of the repetition encountered on a successful match. The job of the transcriber is to sort that structure