aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_mbe')
-rw-r--r--crates/ra_mbe/src/lib.rs20
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs14
2 files changed, 24 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs
index 2c75b7b4f..989308626 100644
--- a/crates/ra_mbe/src/lib.rs
+++ b/crates/ra_mbe/src/lib.rs
@@ -42,7 +42,7 @@ pub use crate::syntax_bridge::{ast_to_token_tree, token_tree_to_ast_item_list};
42/// be very confusing is that AST has almost exactly the same shape as 42/// be very confusing is that AST has almost exactly the same shape as
43/// `tt::TokenTree`, but there's a crucial difference: in macro rules, `$ident` 43/// `tt::TokenTree`, but there's a crucial difference: in macro rules, `$ident`
44/// and `$()*` have special meaning (see `Var` and `Repeat` data structures) 44/// and `$()*` have special meaning (see `Var` and `Repeat` data structures)
45#[derive(Debug, PartialEq, Eq)] 45#[derive(Clone, Debug, PartialEq, Eq)]
46pub struct MacroRules { 46pub struct MacroRules {
47 pub(crate) rules: Vec<Rule>, 47 pub(crate) rules: Vec<Rule>,
48} 48}
@@ -56,13 +56,13 @@ impl MacroRules {
56 } 56 }
57} 57}
58 58
59#[derive(Debug, PartialEq, Eq)] 59#[derive(Clone, Debug, PartialEq, Eq)]
60pub(crate) struct Rule { 60pub(crate) struct Rule {
61 pub(crate) lhs: Subtree, 61 pub(crate) lhs: Subtree,
62 pub(crate) rhs: Subtree, 62 pub(crate) rhs: Subtree,
63} 63}
64 64
65#[derive(Debug, PartialEq, Eq)] 65#[derive(Clone, Debug, PartialEq, Eq)]
66pub(crate) enum TokenTree { 66pub(crate) enum TokenTree {
67 Leaf(Leaf), 67 Leaf(Leaf),
68 Subtree(Subtree), 68 Subtree(Subtree),
@@ -70,7 +70,7 @@ pub(crate) enum TokenTree {
70} 70}
71impl_froms!(TokenTree: Leaf, Subtree, Repeat); 71impl_froms!(TokenTree: Leaf, Subtree, Repeat);
72 72
73#[derive(Debug, PartialEq, Eq)] 73#[derive(Clone, Debug, PartialEq, Eq)]
74pub(crate) enum Leaf { 74pub(crate) enum Leaf {
75 Literal(Literal), 75 Literal(Literal),
76 Punct(Punct), 76 Punct(Punct),
@@ -79,37 +79,37 @@ pub(crate) enum Leaf {
79} 79}
80impl_froms!(Leaf: Literal, Punct, Ident, Var); 80impl_froms!(Leaf: Literal, Punct, Ident, Var);
81 81
82#[derive(Debug, PartialEq, Eq)] 82#[derive(Clone, Debug, PartialEq, Eq)]
83pub(crate) struct Subtree { 83pub(crate) struct Subtree {
84 pub(crate) delimiter: Delimiter, 84 pub(crate) delimiter: Delimiter,
85 pub(crate) token_trees: Vec<TokenTree>, 85 pub(crate) token_trees: Vec<TokenTree>,
86} 86}
87 87
88#[derive(Debug, PartialEq, Eq)] 88#[derive(Clone, Debug, PartialEq, Eq)]
89pub(crate) struct Repeat { 89pub(crate) struct Repeat {
90 pub(crate) subtree: Subtree, 90 pub(crate) subtree: Subtree,
91 pub(crate) kind: RepeatKind, 91 pub(crate) kind: RepeatKind,
92 pub(crate) separator: Option<char>, 92 pub(crate) separator: Option<char>,
93} 93}
94 94
95#[derive(Debug, PartialEq, Eq)] 95#[derive(Clone, Debug, PartialEq, Eq)]
96pub(crate) enum RepeatKind { 96pub(crate) enum RepeatKind {
97 ZeroOrMore, 97 ZeroOrMore,
98 OneOrMore, 98 OneOrMore,
99 ZeroOrOne, 99 ZeroOrOne,
100} 100}
101 101
102#[derive(Debug, PartialEq, Eq)] 102#[derive(Clone, Debug, PartialEq, Eq)]
103pub(crate) struct Literal { 103pub(crate) struct Literal {
104 pub(crate) text: SmolStr, 104 pub(crate) text: SmolStr,
105} 105}
106 106
107#[derive(Debug, PartialEq, Eq)] 107#[derive(Clone, Debug, PartialEq, Eq)]
108pub(crate) struct Ident { 108pub(crate) struct Ident {
109 pub(crate) text: SmolStr, 109 pub(crate) text: SmolStr,
110} 110}
111 111
112#[derive(Debug, PartialEq, Eq)] 112#[derive(Clone, Debug, PartialEq, Eq)]
113pub(crate) struct Var { 113pub(crate) struct Var {
114 pub(crate) text: SmolStr, 114 pub(crate) text: SmolStr,
115 pub(crate) kind: Option<SmolStr>, 115 pub(crate) kind: Option<SmolStr>,
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 2dd97b665..2dafd68f6 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -155,7 +155,14 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
155 _ => return Err(ExpandError::UnexpectedToken), 155 _ => return Err(ExpandError::UnexpectedToken),
156 }, 156 },
157 crate::TokenTree::Repeat(crate::Repeat { subtree, kind: _, separator }) => { 157 crate::TokenTree::Repeat(crate::Repeat { subtree, kind: _, separator }) => {
158 // Dirty hack to make macro-expansion terminate.
159 // This should be replaced by a propper macro-by-example implementation
160 let mut limit = 128;
158 while let Ok(nested) = match_lhs(subtree, input) { 161 while let Ok(nested) = match_lhs(subtree, input) {
162 limit -= 1;
163 if limit == 0 {
164 break;
165 }
159 res.push_nested(nested)?; 166 res.push_nested(nested)?;
160 if let Some(separator) = *separator { 167 if let Some(separator) = *separator {
161 if !input.is_eof() { 168 if !input.is_eof() {
@@ -196,7 +203,14 @@ fn expand_tt(
196 crate::TokenTree::Repeat(repeat) => { 203 crate::TokenTree::Repeat(repeat) => {
197 let mut token_trees = Vec::new(); 204 let mut token_trees = Vec::new();
198 nesting.push(0); 205 nesting.push(0);
206 // Dirty hack to make macro-expansion terminate.
207 // This should be replaced by a propper macro-by-example implementation
208 let mut limit = 128;
199 while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) { 209 while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) {
210 limit -= 1;
211 if limit == 0 {
212 break;
213 }
200 let idx = nesting.pop().unwrap(); 214 let idx = nesting.pop().unwrap();
201 nesting.push(idx + 1); 215 nesting.push(idx + 1);
202 token_trees.push(t.into()) 216 token_trees.push(t.into())