diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 5623a0b5..aaa68c05 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -53,6 +53,7 @@ - [Macros](rust-2018/macros/index.md) - [Custom Derive](rust-2018/macros/custom-derive.md) - [Macro changes](rust-2018/macros/macro-changes.md) + - [At most one repetition](rust-2018/macros/at-most-once.md) - [The compiler](rust-2018/the-compiler/index.md) - [Improved error messages](rust-2018/the-compiler/improved-error-messages.md) - [Incremental Compilation for faster compiles](rust-2018/the-compiler/incremental-compilation-for-faster-compiles.md) diff --git a/src/rust-2018/macros/at-most-once.md b/src/rust-2018/macros/at-most-once.md new file mode 100644 index 00000000..fb38610d --- /dev/null +++ b/src/rust-2018/macros/at-most-once.md @@ -0,0 +1,38 @@ +# At most one repetition + +In Rust 2018, we have made a couple of changes to the macros-by-example syntax. + +1. We have added a new Kleene operator `?` which means "at most one" + repetition. This operator does not accept a separator token. +2. We have disallowed using `?` as a separator to remove ambiguity with `?`. + +For example, consider the following Rust 2015 code: + +```rust2018 +macro_rules! foo { + ($a:ident, $b:expr) => { + println!("{}", $a); + println!("{}", $b); + } + ($a:ident) => { + println!("{}", $a); + } +} +``` + +Macro `foo` can be called with 1 or 2 arguments; the second one is optional, +but you need a whole other matcher to represent this possibility. This is +annoying if your matchers are long. In Rust 2018, one can simply write the +following: + +```rust2018 +macro_rules! foo { + ($a:ident $(, $b:expr)?) => { + println!("{}", $a); + + $( + println!("{}", $b); + )? + } +} +```