From 9cc038897e8fd1fc9884dd51f09baf4a5c83c9cd Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 17 Mar 2018 14:58:56 +0900 Subject: [PATCH 1/3] Add a test for #2538 --- tests/source/macro_rules.rs | 16 ++++++++++++++++ tests/target/macro_rules.rs | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/source/macro_rules.rs b/tests/source/macro_rules.rs index dba1d78f0dd3..ea3cefa87386 100644 --- a/tests/source/macro_rules.rs +++ b/tests/source/macro_rules.rs @@ -112,3 +112,19 @@ macro foo($type_name: ident, $docs: expr) { #[derive(Debug, Clone, Copy)] pub struct $type_name; } + +// #2538 +macro_rules! add_message_to_notes { + ($msg:expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }} +} diff --git a/tests/target/macro_rules.rs b/tests/target/macro_rules.rs index 2136784dec77..bc9c6aa40223 100644 --- a/tests/target/macro_rules.rs +++ b/tests/target/macro_rules.rs @@ -103,3 +103,19 @@ macro foo($type_name: ident, $docs: expr) { #[derive(Debug, Clone, Copy)] pub struct $type_name; } + +// #2538 +macro_rules! add_message_to_notes { + ($msg: expr) => {{ + let mut lines = message.lines(); + notes.push_str(&format!("\n{}: {}", level, lines.next().unwrap())); + for line in lines { + notes.push_str(&format!( + "\n{:indent$}{line}", + "", + indent = level.len() + 2, + line = line, + )); + } + }}; +} From d7188654ea4a0299525caf4196ef366d38c9eb98 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 17 Mar 2018 14:59:26 +0900 Subject: [PATCH 2/3] Skip name replacement in comments and strings --- src/macros.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index b260e15501fc..03f737893109 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -33,7 +33,8 @@ use syntax::tokenstream::{Cursor, ThinTokenStream, TokenStream, TokenTree}; use syntax::util::ThinVec; use codemap::SpanUtils; -use comment::{contains_comment, remove_trailing_white_spaces, FindUncommented}; +use comment::{contains_comment, remove_trailing_white_spaces, CharClasses, FindUncommented, + FullCodeCharKind}; use expr::rewrite_array; use lists::{itemize_list, write_list, ListFormatting}; use overflow; @@ -409,8 +410,10 @@ fn replace_names(input: &str) -> Option<(String, HashMap)> { let mut dollar_count = 0; let mut cur_name = String::new(); - for c in input.chars() { - if c == '$' { + for (kind, c) in CharClasses::new(input.chars()) { + if kind != FullCodeCharKind::Normal { + result.push(c); + } else if c == '$' { dollar_count += 1; } else if dollar_count == 0 { result.push(c); From 1a969cff7fe3dc5cef4f36e1786db5dc22b6ed6a Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Sat, 17 Mar 2018 14:59:39 +0900 Subject: [PATCH 3/3] Remove FIXME about duplicated code --- src/macros.rs | 54 ++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 03f737893109..030988e5195f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -400,6 +400,28 @@ pub fn rewrite_macro_def( Some(result) } +fn register_metavariable( + map: &mut HashMap, + result: &mut String, + name: &str, + dollar_count: usize, +) { + let mut new_name = String::new(); + let mut old_name = String::new(); + + old_name.push('$'); + for _ in 0..(dollar_count - 1) { + new_name.push('$'); + old_name.push('$'); + } + new_name.push('z'); + new_name.push_str(&name); + old_name.push_str(&name); + + result.push_str(&new_name); + map.insert(old_name, new_name); +} + // Replaces `$foo` with `zfoo`. We must check for name overlap to ensure we // aren't causing problems. // This should also work for escaped `$` variables, where we leave earlier `$`s. @@ -419,24 +441,11 @@ fn replace_names(input: &str) -> Option<(String, HashMap)> { result.push(c); } else if !c.is_alphanumeric() && !cur_name.is_empty() { // Terminates a name following one or more dollars. - let mut new_name = String::new(); - let mut old_name = String::new(); - old_name.push('$'); - for _ in 0..(dollar_count - 1) { - new_name.push('$'); - old_name.push('$'); - } - new_name.push('z'); - new_name.push_str(&cur_name); - old_name.push_str(&cur_name); - - result.push_str(&new_name); - substs.insert(old_name, new_name); + register_metavariable(&mut substs, &mut result, &cur_name, dollar_count); result.push(c); - dollar_count = 0; - cur_name = String::new(); + cur_name.clear(); } else if c == '(' && cur_name.is_empty() { // FIXME: Support macro def with repeat. return None; @@ -445,21 +454,8 @@ fn replace_names(input: &str) -> Option<(String, HashMap)> { } } - // FIXME: duplicate code if !cur_name.is_empty() { - let mut new_name = String::new(); - let mut old_name = String::new(); - old_name.push('$'); - for _ in 0..(dollar_count - 1) { - new_name.push('$'); - old_name.push('$'); - } - new_name.push('z'); - new_name.push_str(&cur_name); - old_name.push_str(&cur_name); - - result.push_str(&new_name); - substs.insert(old_name, new_name); + register_metavariable(&mut substs, &mut result, &cur_name, dollar_count); } debug!("replace_names `{}` {:?}", result, substs);