From 0fd174d5f1e51a03b6454617c780f2ea6cd4cb6b Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sun, 18 Mar 2018 13:12:16 +0900 Subject: [PATCH] Handle binary operators and lifetimes --- src/macros.rs | 18 +++++++++++++----- tests/source/macro_rules.rs | 7 +++++++ tests/target/macro_rules.rs | 7 +++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index f71c648baac6..9b5fda2c1ec7 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -669,8 +669,16 @@ impl MacroArgParser { if self.buf.is_empty() { self.lo = lo; self.start_tok = t.clone(); - } else if force_space_before(t) { - self.buf.push(' '); + } else { + let needs_space = match next_space(&self.last_tok) { + SpaceState::Ident => ident_like(t), + SpaceState::Punctuation => !ident_like(t), + SpaceState::Always => true, + SpaceState::Never => false, + }; + if force_space_before(t) || needs_space { + self.buf.push(' '); + } } self.buf.push_str(&pprust::token_to_string(t)); @@ -888,9 +896,9 @@ fn force_space_before(tok: &Token) -> bool { | Token::RArrow | Token::LArrow | Token::FatArrow + | Token::BinOp(_) | Token::Pound | Token::Dollar => true, - Token::BinOp(bot) => bot != BinOpToken::Star, _ => false, } } @@ -907,6 +915,7 @@ fn next_space(tok: &Token) -> SpaceState { match *tok { Token::Not + | Token::BinOp(BinOpToken::And) | Token::Tilde | Token::At | Token::Comma @@ -916,8 +925,7 @@ fn next_space(tok: &Token) -> SpaceState { | Token::DotDotEq | Token::DotEq | Token::Question - | Token::Underscore - | Token::BinOp(_) => SpaceState::Punctuation, + | Token::Underscore => SpaceState::Punctuation, Token::ModSep | Token::Pound diff --git a/tests/source/macro_rules.rs b/tests/source/macro_rules.rs index 2d0d0e80a6b2..1a4d81316002 100644 --- a/tests/source/macro_rules.rs +++ b/tests/source/macro_rules.rs @@ -10,6 +10,13 @@ macro_rules! m { ( $( $ i : ident : $ ty : ty , $def : expr , $stb : expr , $ ( $ dstring : tt ) , + ) ; + $ ( ; ) * $( $ i : ident : $ ty : ty , $def : expr , $stb : expr , $ ( $ dstring : tt ) , + ) ; + $ ( ; ) * ) => {}; + ( $foo: tt foo [$ attr : meta] $name: ident ) => {}; + ( $foo: tt [$ attr: meta] $name: ident ) => {}; + ( $foo: tt &'a [$attr : meta] $name: ident ) => {}; + ( $foo: tt foo # [ $attr : meta] $name: ident ) => {}; + ( $foo: tt # [ $attr : meta] $name: ident) => {}; + ( $foo: tt &'a # [ $attr : meta] $name: ident ) => {}; + ( $ x : tt foo bar foo bar foo bar $ y : tt => x*y*z $ z : tt , $ ( $a: tt ) , * ) => {}; } macro_rules! m { diff --git a/tests/target/macro_rules.rs b/tests/target/macro_rules.rs index 54d7dde68427..ece163991848 100644 --- a/tests/target/macro_rules.rs +++ b/tests/target/macro_rules.rs @@ -18,6 +18,13 @@ macro_rules! m { $($i: ident: $ty: ty, $def: expr, $stb: expr, $($dstring: tt),+);+ $(;)* $($i: ident: $ty: ty, $def: expr, $stb: expr, $($dstring: tt),+);+ $(;)* ) => {}; + ($foo: tt foo[$attr: meta] $name: ident) => {}; + ($foo: tt[$attr: meta] $name: ident) => {}; + ($foo: tt &'a[$attr: meta] $name: ident) => {}; + ($foo: tt foo #[$attr: meta] $name: ident) => {}; + ($foo: tt #[$attr: meta] $name: ident) => {}; + ($foo: tt &'a #[$attr: meta] $name: ident) => {}; + ($x: tt foo bar foo bar foo bar $y: tt => x * y * z $z: tt, $($a: tt),*) => {}; } macro_rules! m {