diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-28 05:07:09 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-28 05:07:09 +0000 |
commit | e0437f899ceea242173c665f7d124c485b680a7a (patch) | |
tree | 0e623f162d68d88de13c50cfe5b3ff05bc4bf27c /crates/mbe/src/syntax_bridge.rs | |
parent | cbec9958220a7ce5d51289e2fc59c2eb0754ac87 (diff) | |
parent | f5bf1a9650089ec7bd0a4d3fb69706fab06da308 (diff) |
Merge #7802
7802: Fix builtin macros split exprs on comma r=edwin0cheng a=edwin0cheng
Fixes #7640
bors r+
Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/mbe/src/syntax_bridge.rs')
-rw-r--r-- | crates/mbe/src/syntax_bridge.rs | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index 0cdc175be..5a91781fc 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs | |||
@@ -10,8 +10,8 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | use tt::buffer::{Cursor, TokenBuffer}; | 11 | use tt::buffer::{Cursor, TokenBuffer}; |
12 | 12 | ||
13 | use crate::subtree_source::SubtreeTokenSource; | ||
14 | use crate::ExpandError; | 13 | use crate::ExpandError; |
14 | use crate::{subtree_source::SubtreeTokenSource, tt_iter::TtIter}; | ||
15 | 15 | ||
16 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 16 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
17 | pub enum TokenTextRange { | 17 | pub enum TokenTextRange { |
@@ -112,6 +112,43 @@ pub fn parse_to_token_tree(text: &str) -> Option<(tt::Subtree, TokenMap)> { | |||
112 | Some((subtree, conv.id_alloc.map)) | 112 | Some((subtree, conv.id_alloc.map)) |
113 | } | 113 | } |
114 | 114 | ||
115 | /// Split token tree with seperate expr: $($e:expr)SEP* | ||
116 | pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char) -> Vec<tt::Subtree> { | ||
117 | if tt.token_trees.is_empty() { | ||
118 | return Vec::new(); | ||
119 | } | ||
120 | |||
121 | let mut iter = TtIter::new(tt); | ||
122 | let mut res = Vec::new(); | ||
123 | |||
124 | while iter.peek_n(0).is_some() { | ||
125 | let expanded = iter.expect_fragment(FragmentKind::Expr); | ||
126 | if expanded.err.is_some() { | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | res.push(match expanded.value { | ||
131 | None => break, | ||
132 | Some(tt @ tt::TokenTree::Leaf(_)) => { | ||
133 | tt::Subtree { delimiter: None, token_trees: vec![tt.into()] } | ||
134 | } | ||
135 | Some(tt::TokenTree::Subtree(tt)) => tt, | ||
136 | }); | ||
137 | |||
138 | let mut fork = iter.clone(); | ||
139 | if fork.expect_char(sep).is_err() { | ||
140 | break; | ||
141 | } | ||
142 | iter = fork; | ||
143 | } | ||
144 | |||
145 | if iter.peek_n(0).is_some() { | ||
146 | res.push(tt::Subtree { delimiter: None, token_trees: iter.into_iter().cloned().collect() }); | ||
147 | } | ||
148 | |||
149 | res | ||
150 | } | ||
151 | |||
115 | impl TokenMap { | 152 | impl TokenMap { |
116 | pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> { | 153 | pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> { |
117 | let &(token_id, _) = self.entries.iter().find(|(_, range)| match range { | 154 | let &(token_id, _) = self.entries.iter().find(|(_, range)| match range { |