aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/mbe_expander
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/mbe_expander')
-rw-r--r--crates/mbe/src/mbe_expander/matcher.rs10
-rw-r--r--crates/mbe/src/mbe_expander/transcriber.rs35
2 files changed, 16 insertions, 29 deletions
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index ab5f87c48..d32e60521 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -150,7 +150,7 @@ fn match_subtree(
150 res.add_err(err!("leftover tokens")); 150 res.add_err(err!("leftover tokens"));
151 } 151 }
152 } 152 }
153 Op::Var { name, kind } => { 153 Op::Var { name, kind, .. } => {
154 let kind = match kind { 154 let kind = match kind {
155 Some(k) => k, 155 Some(k) => k,
156 None => { 156 None => {
@@ -309,7 +309,7 @@ impl<'a> TtIter<'a> {
309 } 309 }
310 } 310 }
311 311
312 let buffer = TokenBuffer::new(&self.inner.as_slice()); 312 let buffer = TokenBuffer::from_tokens(&self.inner.as_slice());
313 let mut src = SubtreeTokenSource::new(&buffer); 313 let mut src = SubtreeTokenSource::new(&buffer);
314 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; 314 let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false };
315 315
@@ -336,11 +336,11 @@ impl<'a> TtIter<'a> {
336 err = Some(err!("no tokens consumed")); 336 err = Some(err!("no tokens consumed"));
337 } 337 }
338 let res = match res.len() { 338 let res = match res.len() {
339 1 => Some(res[0].clone()), 339 1 => Some(res[0].cloned()),
340 0 => None, 340 0 => None,
341 _ => Some(tt::TokenTree::Subtree(tt::Subtree { 341 _ => Some(tt::TokenTree::Subtree(tt::Subtree {
342 delimiter: None, 342 delimiter: None,
343 token_trees: res.into_iter().cloned().collect(), 343 token_trees: res.into_iter().map(|it| it.cloned()).collect(),
344 })), 344 })),
345 }; 345 };
346 ExpandResult { value: res, err } 346 ExpandResult { value: res, err }
@@ -378,7 +378,7 @@ pub(super) fn match_repeat(
378 src: &mut TtIter, 378 src: &mut TtIter,
379) -> Result<(), ExpandError> { 379) -> Result<(), ExpandError> {
380 // Dirty hack to make macro-expansion terminate. 380 // Dirty hack to make macro-expansion terminate.
381 // This should be replaced by a propper macro-by-example implementation 381 // This should be replaced by a proper macro-by-example implementation
382 let mut limit = 65536; 382 let mut limit = 65536;
383 let mut counter = 0; 383 let mut counter = 0;
384 384
diff --git a/crates/mbe/src/mbe_expander/transcriber.rs b/crates/mbe/src/mbe_expander/transcriber.rs
index 720531237..59a3c80a8 100644
--- a/crates/mbe/src/mbe_expander/transcriber.rs
+++ b/crates/mbe/src/mbe_expander/transcriber.rs
@@ -67,7 +67,7 @@ struct NestingState {
67 /// because there is no variable in use by the current repetition 67 /// because there is no variable in use by the current repetition
68 hit: bool, 68 hit: bool,
69 /// `at_end` is currently necessary to tell `expand_repeat` if it should stop 69 /// `at_end` is currently necessary to tell `expand_repeat` if it should stop
70 /// because there is no more value avaible for the current repetition 70 /// because there is no more value available for the current repetition
71 at_end: bool, 71 at_end: bool,
72} 72}
73 73
@@ -100,8 +100,8 @@ fn expand_subtree(
100 err = err.or(e); 100 err = err.or(e);
101 arena.push(tt.into()); 101 arena.push(tt.into());
102 } 102 }
103 Op::Var { name, .. } => { 103 Op::Var { name, id, .. } => {
104 let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name); 104 let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name, *id);
105 err = err.or(e); 105 err = err.or(e);
106 push_fragment(arena, fragment); 106 push_fragment(arena, fragment);
107 } 107 }
@@ -118,14 +118,11 @@ fn expand_subtree(
118 ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err } 118 ExpandResult { value: tt::Subtree { delimiter: template.delimiter, token_trees: tts }, err }
119} 119}
120 120
121fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> { 121fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult<Fragment> {
122 if v == "crate" { 122 // We already handle $crate case in mbe parser
123 // We simply produce identifier `$crate` here. And it will be resolved when lowering ast to Path. 123 debug_assert!(v != "crate");
124 let tt = 124
125 tt::Leaf::from(tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() }) 125 if !ctx.bindings.contains(v) {
126 .into();
127 ExpandResult::ok(Fragment::Tokens(tt))
128 } else if !ctx.bindings.contains(v) {
129 // Note that it is possible to have a `$var` inside a macro which is not bound. 126 // Note that it is possible to have a `$var` inside a macro which is not bound.
130 // For example: 127 // For example:
131 // ``` 128 // ```
@@ -142,14 +139,8 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> ExpandResult<Fragment> {
142 let tt = tt::Subtree { 139 let tt = tt::Subtree {
143 delimiter: None, 140 delimiter: None,
144 token_trees: vec![ 141 token_trees: vec![
145 tt::Leaf::from(tt::Punct { 142 tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone, id }).into(),
146 char: '$', 143 tt::Leaf::from(tt::Ident { text: v.clone(), id }).into(),
147 spacing: tt::Spacing::Alone,
148 id: tt::TokenId::unspecified(),
149 })
150 .into(),
151 tt::Leaf::from(tt::Ident { text: v.clone(), id: tt::TokenId::unspecified() })
152 .into(),
153 ], 144 ],
154 } 145 }
155 .into(); 146 .into();
@@ -188,11 +179,7 @@ fn expand_repeat(
188 179
189 counter += 1; 180 counter += 1;
190 if counter == limit { 181 if counter == limit {
191 log::warn!( 182 log::warn!("expand_tt in repeat pattern exceed limit => {:#?}\n{:#?}", template, ctx);
192 "expand_tt excced in repeat pattern exceed limit => {:#?}\n{:#?}",
193 template,
194 ctx
195 );
196 break; 183 break;
197 } 184 }
198 185