From f21655ec0286769056c73f9b1c847936c577004b Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Fri, 22 May 2015 10:37:44 -0400 Subject: [PATCH] Allow patterns to be followed by if and in. Needed to support: match X { pattern if Y ... } for pattern in Y {} --- src/doc/trpl/macros.md | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 1 + src/test/run-pass/macro-pat-follow.rs | 30 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/macro-pat-follow.rs diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index a45d4824f4123..0f9a01645199a 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -478,7 +478,7 @@ There are additional rules regarding the next token after a metavariable: * `expr` variables may only be followed by one of: `=> , ;` * `ty` and `path` variables may only be followed by one of: `=> , : = > as` -* `pat` variables may only be followed by one of: `=> , =` +* `pat` variables may only be followed by one of: `=> , = if in` * Other variables may be followed by any token. These rules provide some flexibility for Rust’s syntax to evolve without diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index febfc7a97fe3d..03d4e21a941bf 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -495,6 +495,7 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result { "pat" => { match *tok { FatArrow | Comma | Eq => Ok(true), + Ident(i, _) if i.as_str() == "if" || i.as_str() == "in" => Ok(true), _ => Ok(false) } }, diff --git a/src/test/run-pass/macro-pat-follow.rs b/src/test/run-pass/macro-pat-follow.rs new file mode 100644 index 0000000000000..77c6ed4447f11 --- /dev/null +++ b/src/test/run-pass/macro-pat-follow.rs @@ -0,0 +1,30 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! pat_in { + ($p:pat in $e:expr) => {{ + let mut iter = $e.into_iter(); + while let $p = iter.next() {} + }} +} + +macro_rules! pat_if { + ($p:pat if $e:expr) => {{ + match Some(1u8) { + $p if $e => {}, + _ => {} + } + }} +} + +fn main() { + pat_in!(Some(_) in 0..10); + pat_if!(Some(x) if x > 0); +}