diff options
Diffstat (limited to 'crates/mbe')
-rw-r--r-- | crates/mbe/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/mbe/src/benchmark.rs | 2 | ||||
-rw-r--r-- | crates/mbe/src/expander/matcher.rs | 41 | ||||
-rw-r--r-- | crates/mbe/src/expander/transcriber.rs | 8 | ||||
-rw-r--r-- | crates/mbe/src/lib.rs | 16 | ||||
-rw-r--r-- | crates/mbe/src/parser.rs | 16 | ||||
-rw-r--r-- | crates/mbe/src/subtree_source.rs | 6 | ||||
-rw-r--r-- | crates/mbe/src/syntax_bridge.rs | 7 | ||||
-rw-r--r-- | crates/mbe/src/tests/expand.rs | 44 | ||||
-rw-r--r-- | crates/mbe/src/tt_iter.rs | 4 |
10 files changed, 70 insertions, 76 deletions
diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml index 8856787c0..f3092d9aa 100644 --- a/crates/mbe/Cargo.toml +++ b/crates/mbe/Cargo.toml | |||
@@ -10,7 +10,7 @@ edition = "2018" | |||
10 | doctest = false | 10 | doctest = false |
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | cov-mark = { version = "1.1", features = ["thread-local"] } | 13 | cov-mark = "2.0.0-pre.1" |
14 | rustc-hash = "1.1.0" | 14 | rustc-hash = "1.1.0" |
15 | smallvec = "1.2.0" | 15 | smallvec = "1.2.0" |
16 | log = "0.4.8" | 16 | log = "0.4.8" |
diff --git a/crates/mbe/src/benchmark.rs b/crates/mbe/src/benchmark.rs index 38707ffa5..18eb97f0d 100644 --- a/crates/mbe/src/benchmark.rs +++ b/crates/mbe/src/benchmark.rs | |||
@@ -187,7 +187,7 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt | |||
187 | let a = 1664525; | 187 | let a = 1664525; |
188 | let c = 1013904223; | 188 | let c = 1013904223; |
189 | *seed = usize::wrapping_add(usize::wrapping_mul(*seed, a), c); | 189 | *seed = usize::wrapping_add(usize::wrapping_mul(*seed, a), c); |
190 | return *seed; | 190 | *seed |
191 | } | 191 | } |
192 | fn make_ident(ident: &str) -> tt::TokenTree { | 192 | fn make_ident(ident: &str) -> tt::TokenTree { |
193 | tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), text: SmolStr::new(ident) }) | 193 | tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), text: SmolStr::new(ident) }) |
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 84ca3ff87..c2a9a38c9 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! An NFA-based parser, which is porting from rustc mbe parsing code | 1 | //! An NFA-based parser, which is porting from rustc mbe parsing code |
2 | //! | 2 | //! |
3 | //! See https://github.com/rust-lang/rust/blob/70b18bc2cbac4712020019f5bf57c00905373205/compiler/rustc_expand/src/mbe/macro_parser.rs | 3 | //! See <https://github.com/rust-lang/rust/blob/70b18bc2cbac4712020019f5bf57c00905373205/compiler/rustc_expand/src/mbe/macro_parser.rs> |
4 | //! Here is a quick intro to how the parser works, copied from rustc: | 4 | //! Here is a quick intro to how the parser works, copied from rustc: |
5 | //! | 5 | //! |
6 | //! A 'position' is a dot in the middle of a matcher, usually represented as a | 6 | //! A 'position' is a dot in the middle of a matcher, usually represented as a |
@@ -121,7 +121,7 @@ impl Match { | |||
121 | 121 | ||
122 | /// Matching errors are added to the `Match`. | 122 | /// Matching errors are added to the `Match`. |
123 | pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree) -> Match { | 123 | pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree) -> Match { |
124 | let mut res = match_loop(pattern, &input); | 124 | let mut res = match_loop(pattern, input); |
125 | res.bound_count = count(res.bindings.bindings()); | 125 | res.bound_count = count(res.bindings.bindings()); |
126 | return res; | 126 | return res; |
127 | 127 | ||
@@ -202,7 +202,7 @@ impl BindingsBuilder { | |||
202 | } | 202 | } |
203 | 203 | ||
204 | fn push_nested(&mut self, parent: &mut BindingsIdx, child: &BindingsIdx) { | 204 | fn push_nested(&mut self, parent: &mut BindingsIdx, child: &BindingsIdx) { |
205 | let BindingsIdx(idx, nidx) = self.copy(&child); | 205 | let BindingsIdx(idx, nidx) = self.copy(child); |
206 | self.nodes[parent.0].push(LinkNode::Node(Rc::new(BindingKind::Nested(idx, nidx)))); | 206 | self.nodes[parent.0].push(LinkNode::Node(Rc::new(BindingKind::Nested(idx, nidx)))); |
207 | } | 207 | } |
208 | 208 | ||
@@ -219,9 +219,9 @@ impl BindingsBuilder { | |||
219 | bindings | 219 | bindings |
220 | } | 220 | } |
221 | 221 | ||
222 | fn build_inner(&self, bindings: &mut Bindings, link_nodes: &Vec<LinkNode<Rc<BindingKind>>>) { | 222 | fn build_inner(&self, bindings: &mut Bindings, link_nodes: &[LinkNode<Rc<BindingKind>>]) { |
223 | let mut nodes = Vec::new(); | 223 | let mut nodes = Vec::new(); |
224 | self.collect_nodes(&link_nodes, &mut nodes); | 224 | self.collect_nodes(link_nodes, &mut nodes); |
225 | 225 | ||
226 | for cmd in nodes { | 226 | for cmd in nodes { |
227 | match &**cmd { | 227 | match &**cmd { |
@@ -282,7 +282,7 @@ impl BindingsBuilder { | |||
282 | 282 | ||
283 | nested_refs.into_iter().for_each(|iter| { | 283 | nested_refs.into_iter().for_each(|iter| { |
284 | let mut child_bindings = Bindings::default(); | 284 | let mut child_bindings = Bindings::default(); |
285 | self.build_inner(&mut child_bindings, &iter); | 285 | self.build_inner(&mut child_bindings, iter); |
286 | nested.push(child_bindings) | 286 | nested.push(child_bindings) |
287 | }) | 287 | }) |
288 | } | 288 | } |
@@ -301,7 +301,7 @@ impl BindingsBuilder { | |||
301 | 301 | ||
302 | fn collect_nodes<'a>( | 302 | fn collect_nodes<'a>( |
303 | &'a self, | 303 | &'a self, |
304 | link_nodes: &'a Vec<LinkNode<Rc<BindingKind>>>, | 304 | link_nodes: &'a [LinkNode<Rc<BindingKind>>], |
305 | nodes: &mut Vec<&'a Rc<BindingKind>>, | 305 | nodes: &mut Vec<&'a Rc<BindingKind>>, |
306 | ) { | 306 | ) { |
307 | link_nodes.iter().for_each(|it| match it { | 307 | link_nodes.iter().for_each(|it| match it { |
@@ -417,7 +417,7 @@ fn match_loop_inner<'t>( | |||
417 | let sep_len = item.sep.as_ref().map_or(0, Separator::tt_count); | 417 | let sep_len = item.sep.as_ref().map_or(0, Separator::tt_count); |
418 | if item.sep.is_some() && sep_idx != sep_len { | 418 | if item.sep.is_some() && sep_idx != sep_len { |
419 | let sep = item.sep.as_ref().unwrap(); | 419 | let sep = item.sep.as_ref().unwrap(); |
420 | if src.clone().expect_separator(&sep, sep_idx) { | 420 | if src.clone().expect_separator(sep, sep_idx) { |
421 | item.dot.next(); | 421 | item.dot.next(); |
422 | item.sep_parsed = Some(sep_idx + 1); | 422 | item.sep_parsed = Some(sep_idx + 1); |
423 | try_push!(next_items, item); | 423 | try_push!(next_items, item); |
@@ -487,22 +487,15 @@ fn match_loop_inner<'t>( | |||
487 | item.meta_result = Some((fork, match_res)); | 487 | item.meta_result = Some((fork, match_res)); |
488 | try_push!(bb_items, item); | 488 | try_push!(bb_items, item); |
489 | } else { | 489 | } else { |
490 | bindings_builder.push_optional(&mut item.bindings, &name); | 490 | bindings_builder.push_optional(&mut item.bindings, name); |
491 | item.dot.next(); | 491 | item.dot.next(); |
492 | cur_items.push(item); | 492 | cur_items.push(item); |
493 | } | 493 | } |
494 | } | 494 | } |
495 | Some(err) => { | 495 | Some(err) => { |
496 | res.add_err(err); | 496 | res.add_err(err); |
497 | match match_res.value { | 497 | if let Some(fragment) = match_res.value { |
498 | Some(fragment) => { | 498 | bindings_builder.push_fragment(&mut item.bindings, name, fragment); |
499 | bindings_builder.push_fragment( | ||
500 | &mut item.bindings, | ||
501 | &name, | ||
502 | fragment, | ||
503 | ); | ||
504 | } | ||
505 | _ => {} | ||
506 | } | 499 | } |
507 | item.is_error = true; | 500 | item.is_error = true; |
508 | error_items.push(item); | 501 | error_items.push(item); |
@@ -511,7 +504,7 @@ fn match_loop_inner<'t>( | |||
511 | } | 504 | } |
512 | } | 505 | } |
513 | OpDelimited::Op(Op::Leaf(leaf)) => { | 506 | OpDelimited::Op(Op::Leaf(leaf)) => { |
514 | if let Err(err) = match_leaf(&leaf, &mut src.clone()) { | 507 | if let Err(err) = match_leaf(leaf, &mut src.clone()) { |
515 | res.add_err(err); | 508 | res.add_err(err); |
516 | item.is_error = true; | 509 | item.is_error = true; |
517 | } else { | 510 | } else { |
@@ -578,9 +571,9 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match { | |||
578 | ); | 571 | ); |
579 | stdx::always!(cur_items.is_empty()); | 572 | stdx::always!(cur_items.is_empty()); |
580 | 573 | ||
581 | if error_items.len() > 0 { | 574 | if !error_items.is_empty() { |
582 | error_recover_item = error_items.pop().map(|it| it.bindings); | 575 | error_recover_item = error_items.pop().map(|it| it.bindings); |
583 | } else if eof_items.len() > 0 { | 576 | } else if !eof_items.is_empty() { |
584 | error_recover_item = Some(eof_items[0].bindings.clone()); | 577 | error_recover_item = Some(eof_items[0].bindings.clone()); |
585 | } | 578 | } |
586 | 579 | ||
@@ -647,10 +640,10 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match { | |||
647 | let (iter, match_res) = item.meta_result.take().unwrap(); | 640 | let (iter, match_res) = item.meta_result.take().unwrap(); |
648 | match match_res.value { | 641 | match match_res.value { |
649 | Some(fragment) => { | 642 | Some(fragment) => { |
650 | bindings_builder.push_fragment(&mut item.bindings, &name, fragment); | 643 | bindings_builder.push_fragment(&mut item.bindings, name, fragment); |
651 | } | 644 | } |
652 | None if match_res.err.is_none() => { | 645 | None if match_res.err.is_none() => { |
653 | bindings_builder.push_optional(&mut item.bindings, &name); | 646 | bindings_builder.push_optional(&mut item.bindings, name); |
654 | } | 647 | } |
655 | _ => {} | 648 | _ => {} |
656 | } | 649 | } |
@@ -793,7 +786,7 @@ impl<'a> TtIter<'a> { | |||
793 | _ => (), | 786 | _ => (), |
794 | } | 787 | } |
795 | 788 | ||
796 | let tt = self.next().ok_or_else(|| ())?.clone(); | 789 | let tt = self.next().ok_or(())?.clone(); |
797 | let punct = match tt { | 790 | let punct = match tt { |
798 | tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => { | 791 | tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => { |
799 | punct | 792 | punct |
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs index dd7fa97d7..49a137577 100644 --- a/crates/mbe/src/expander/transcriber.rs +++ b/crates/mbe/src/expander/transcriber.rs | |||
@@ -55,7 +55,7 @@ pub(super) fn transcribe( | |||
55 | template: &MetaTemplate, | 55 | template: &MetaTemplate, |
56 | bindings: &Bindings, | 56 | bindings: &Bindings, |
57 | ) -> ExpandResult<tt::Subtree> { | 57 | ) -> ExpandResult<tt::Subtree> { |
58 | let mut ctx = ExpandCtx { bindings: &bindings, nesting: Vec::new() }; | 58 | let mut ctx = ExpandCtx { bindings, nesting: Vec::new() }; |
59 | let mut arena: Vec<tt::TokenTree> = Vec::new(); | 59 | let mut arena: Vec<tt::TokenTree> = Vec::new(); |
60 | expand_subtree(&mut ctx, template, None, &mut arena) | 60 | expand_subtree(&mut ctx, template, None, &mut arena) |
61 | } | 61 | } |
@@ -91,12 +91,12 @@ fn expand_subtree( | |||
91 | Op::Leaf(tt) => arena.push(tt.clone().into()), | 91 | Op::Leaf(tt) => arena.push(tt.clone().into()), |
92 | Op::Subtree { tokens, delimiter } => { | 92 | Op::Subtree { tokens, delimiter } => { |
93 | let ExpandResult { value: tt, err: e } = | 93 | let ExpandResult { value: tt, err: e } = |
94 | expand_subtree(ctx, &tokens, *delimiter, arena); | 94 | expand_subtree(ctx, tokens, *delimiter, arena); |
95 | err = err.or(e); | 95 | err = err.or(e); |
96 | arena.push(tt.into()); | 96 | arena.push(tt.into()); |
97 | } | 97 | } |
98 | Op::Var { name, id, .. } => { | 98 | Op::Var { name, id, .. } => { |
99 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, &name, *id); | 99 | let ExpandResult { value: fragment, err: e } = expand_var(ctx, name, *id); |
100 | err = err.or(e); | 100 | err = err.or(e); |
101 | push_fragment(arena, fragment); | 101 | push_fragment(arena, fragment); |
102 | } | 102 | } |
@@ -141,7 +141,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr, id: tt::TokenId) -> ExpandResult | |||
141 | .into(); | 141 | .into(); |
142 | ExpandResult::ok(Fragment::Tokens(tt)) | 142 | ExpandResult::ok(Fragment::Tokens(tt)) |
143 | } else { | 143 | } else { |
144 | ctx.bindings.get(&v, &mut ctx.nesting).map_or_else( | 144 | ctx.bindings.get(v, &mut ctx.nesting).map_or_else( |
145 | |e| ExpandResult { value: Fragment::Tokens(tt::TokenTree::empty()), err: Some(e) }, | 145 | |e| ExpandResult { value: Fragment::Tokens(tt::TokenTree::empty()), err: Some(e) }, |
146 | |b| ExpandResult::ok(b.clone()), | 146 | |b| ExpandResult::ok(b.clone()), |
147 | ) | 147 | ) |
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs index b95374b76..8c8528aaf 100644 --- a/crates/mbe/src/lib.rs +++ b/crates/mbe/src/lib.rs | |||
@@ -280,8 +280,8 @@ impl Rule { | |||
280 | .expect_subtree() | 280 | .expect_subtree() |
281 | .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; | 281 | .map_err(|()| ParseError::Expected("expected subtree".to_string()))?; |
282 | 282 | ||
283 | let lhs = MetaTemplate(parse_pattern(&lhs)?); | 283 | let lhs = MetaTemplate(parse_pattern(lhs)?); |
284 | let rhs = MetaTemplate(parse_template(&rhs)?); | 284 | let rhs = MetaTemplate(parse_template(rhs)?); |
285 | 285 | ||
286 | Ok(crate::Rule { lhs, rhs }) | 286 | Ok(crate::Rule { lhs, rhs }) |
287 | } | 287 | } |
@@ -290,13 +290,13 @@ impl Rule { | |||
290 | fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { | 290 | fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { |
291 | for op in pattern.iter() { | 291 | for op in pattern.iter() { |
292 | match op { | 292 | match op { |
293 | Op::Subtree { tokens, .. } => validate(&tokens)?, | 293 | Op::Subtree { tokens, .. } => validate(tokens)?, |
294 | Op::Repeat { tokens: subtree, separator, .. } => { | 294 | Op::Repeat { tokens: subtree, separator, .. } => { |
295 | // Checks that no repetition which could match an empty token | 295 | // Checks that no repetition which could match an empty token |
296 | // https://github.com/rust-lang/rust/blob/a58b1ed44f5e06976de2bdc4d7dc81c36a96934f/src/librustc_expand/mbe/macro_rules.rs#L558 | 296 | // https://github.com/rust-lang/rust/blob/a58b1ed44f5e06976de2bdc4d7dc81c36a96934f/src/librustc_expand/mbe/macro_rules.rs#L558 |
297 | 297 | ||
298 | if separator.is_none() { | 298 | if separator.is_none() |
299 | if subtree.iter().all(|child_op| { | 299 | && subtree.iter().all(|child_op| { |
300 | match child_op { | 300 | match child_op { |
301 | Op::Var { kind, .. } => { | 301 | Op::Var { kind, .. } => { |
302 | // vis is optional | 302 | // vis is optional |
@@ -314,9 +314,9 @@ fn validate(pattern: &MetaTemplate) -> Result<(), ParseError> { | |||
314 | Op::Subtree { .. } => {} | 314 | Op::Subtree { .. } => {} |
315 | } | 315 | } |
316 | false | 316 | false |
317 | }) { | 317 | }) |
318 | return Err(ParseError::RepetitionEmptyTokenTree); | 318 | { |
319 | } | 319 | return Err(ParseError::RepetitionEmptyTokenTree); |
320 | } | 320 | } |
321 | validate(subtree)? | 321 | validate(subtree)? |
322 | } | 322 | } |
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs index 61b2a4955..deed884d2 100644 --- a/crates/mbe/src/parser.rs +++ b/crates/mbe/src/parser.rs | |||
@@ -42,7 +42,7 @@ impl<'a> OpDelimitedIter<'a> { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | pub(crate) fn reset(&self) -> Self { | 44 | pub(crate) fn reset(&self) -> Self { |
45 | Self { inner: &self.inner, idx: 0, delimited: self.delimited } | 45 | Self { inner: self.inner, idx: 0, delimited: self.delimited } |
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
@@ -126,11 +126,11 @@ impl Separator { | |||
126 | } | 126 | } |
127 | 127 | ||
128 | pub(crate) fn parse_template(template: &tt::Subtree) -> Result<Vec<Op>, ParseError> { | 128 | pub(crate) fn parse_template(template: &tt::Subtree) -> Result<Vec<Op>, ParseError> { |
129 | parse_inner(&template, Mode::Template).into_iter().collect() | 129 | parse_inner(template, Mode::Template).into_iter().collect() |
130 | } | 130 | } |
131 | 131 | ||
132 | pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<Vec<Op>, ParseError> { | 132 | pub(crate) fn parse_pattern(pattern: &tt::Subtree) -> Result<Vec<Op>, ParseError> { |
133 | parse_inner(&pattern, Mode::Pattern).into_iter().collect() | 133 | parse_inner(pattern, Mode::Pattern).into_iter().collect() |
134 | } | 134 | } |
135 | 135 | ||
136 | #[derive(Clone, Copy)] | 136 | #[derive(Clone, Copy)] |
@@ -140,7 +140,7 @@ enum Mode { | |||
140 | } | 140 | } |
141 | 141 | ||
142 | fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ParseError>> { | 142 | fn parse_inner(tt: &tt::Subtree, mode: Mode) -> Vec<Result<Op, ParseError>> { |
143 | let mut src = TtIter::new(&tt); | 143 | let mut src = TtIter::new(tt); |
144 | std::iter::from_fn(move || { | 144 | std::iter::from_fn(move || { |
145 | let first = src.next()?; | 145 | let first = src.next()?; |
146 | Some(next_op(first, &mut src, mode)) | 146 | Some(next_op(first, &mut src, mode)) |
@@ -171,7 +171,7 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
171 | match second { | 171 | match second { |
172 | tt::TokenTree::Subtree(subtree) => { | 172 | tt::TokenTree::Subtree(subtree) => { |
173 | let (separator, kind) = parse_repeat(src)?; | 173 | let (separator, kind) = parse_repeat(src)?; |
174 | let tokens = parse_inner(&subtree, mode) | 174 | let tokens = parse_inner(subtree, mode) |
175 | .into_iter() | 175 | .into_iter() |
176 | .collect::<Result<Vec<Op>, ParseError>>()?; | 176 | .collect::<Result<Vec<Op>, ParseError>>()?; |
177 | Op::Repeat { tokens: MetaTemplate(tokens), separator, kind } | 177 | Op::Repeat { tokens: MetaTemplate(tokens), separator, kind } |
@@ -191,7 +191,7 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
191 | Op::Var { name, kind, id } | 191 | Op::Var { name, kind, id } |
192 | } | 192 | } |
193 | tt::Leaf::Literal(lit) => { | 193 | tt::Leaf::Literal(lit) => { |
194 | if is_boolean_literal(&lit) { | 194 | if is_boolean_literal(lit) { |
195 | let name = lit.text.clone(); | 195 | let name = lit.text.clone(); |
196 | let kind = eat_fragment_kind(src, mode)?; | 196 | let kind = eat_fragment_kind(src, mode)?; |
197 | let id = lit.id; | 197 | let id = lit.id; |
@@ -206,14 +206,14 @@ fn next_op<'a>(first: &tt::TokenTree, src: &mut TtIter<'a>, mode: Mode) -> Resul | |||
206 | tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()), | 206 | tt::TokenTree::Leaf(tt) => Op::Leaf(tt.clone()), |
207 | tt::TokenTree::Subtree(subtree) => { | 207 | tt::TokenTree::Subtree(subtree) => { |
208 | let tokens = | 208 | let tokens = |
209 | parse_inner(&subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?; | 209 | parse_inner(subtree, mode).into_iter().collect::<Result<Vec<Op>, ParseError>>()?; |
210 | Op::Subtree { tokens: MetaTemplate(tokens), delimiter: subtree.delimiter } | 210 | Op::Subtree { tokens: MetaTemplate(tokens), delimiter: subtree.delimiter } |
211 | } | 211 | } |
212 | }; | 212 | }; |
213 | Ok(res) | 213 | Ok(res) |
214 | } | 214 | } |
215 | 215 | ||
216 | fn eat_fragment_kind<'a>(src: &mut TtIter<'a>, mode: Mode) -> Result<Option<SmolStr>, ParseError> { | 216 | fn eat_fragment_kind(src: &mut TtIter<'_>, mode: Mode) -> Result<Option<SmolStr>, ParseError> { |
217 | if let Mode::Pattern = mode { | 217 | if let Mode::Pattern = mode { |
218 | src.expect_char(':').map_err(|()| err!("bad fragment specifier 1"))?; | 218 | src.expect_char(':').map_err(|()| err!("bad fragment specifier 1"))?; |
219 | let ident = src.expect_ident().map_err(|()| err!("bad fragment specifier 1"))?; | 219 | let ident = src.expect_ident().map_err(|()| err!("bad fragment specifier 1"))?; |
diff --git a/crates/mbe/src/subtree_source.rs b/crates/mbe/src/subtree_source.rs index bde370fdb..ee80807ad 100644 --- a/crates/mbe/src/subtree_source.rs +++ b/crates/mbe/src/subtree_source.rs | |||
@@ -22,7 +22,7 @@ impl<'a> SubtreeTokenSource { | |||
22 | #[cfg(test)] | 22 | #[cfg(test)] |
23 | pub(crate) fn text(&self) -> SmolStr { | 23 | pub(crate) fn text(&self) -> SmolStr { |
24 | match self.cached.get(self.curr.1) { | 24 | match self.cached.get(self.curr.1) { |
25 | Some(ref tt) => tt.text.clone(), | 25 | Some(tt) => tt.text.clone(), |
26 | _ => SmolStr::new(""), | 26 | _ => SmolStr::new(""), |
27 | } | 27 | } |
28 | } | 28 | } |
@@ -59,7 +59,7 @@ impl<'a> SubtreeTokenSource { | |||
59 | 59 | ||
60 | current = match tt { | 60 | current = match tt { |
61 | Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { | 61 | Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { |
62 | cached.push(convert_leaf(&leaf)); | 62 | cached.push(convert_leaf(leaf)); |
63 | cursor.bump() | 63 | cursor.bump() |
64 | } | 64 | } |
65 | Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) => { | 65 | Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) => { |
@@ -114,7 +114,7 @@ impl<'a> TokenSource for SubtreeTokenSource { | |||
114 | /// Is the current token a specified keyword? | 114 | /// Is the current token a specified keyword? |
115 | fn is_keyword(&self, kw: &str) -> bool { | 115 | fn is_keyword(&self, kw: &str) -> bool { |
116 | match self.cached.get(self.curr.1) { | 116 | match self.cached.get(self.curr.1) { |
117 | Some(ref t) => t.text == *kw, | 117 | Some(t) => t.text == *kw, |
118 | _ => false, | 118 | _ => false, |
119 | } | 119 | } |
120 | } | 120 | } |
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index b11172caf..cdc22425d 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs | |||
@@ -243,8 +243,7 @@ trait TokenConvertor { | |||
243 | type Token: SrcToken; | 243 | type Token: SrcToken; |
244 | 244 | ||
245 | fn go(&mut self) -> tt::Subtree { | 245 | fn go(&mut self) -> tt::Subtree { |
246 | let mut subtree = tt::Subtree::default(); | 246 | let mut subtree = tt::Subtree { delimiter: None, ..Default::default() }; |
247 | subtree.delimiter = None; | ||
248 | while self.peek().is_some() { | 247 | while self.peek().is_some() { |
249 | self.collect_leaf(&mut subtree.token_trees); | 248 | self.collect_leaf(&mut subtree.token_trees); |
250 | } | 249 | } |
@@ -506,7 +505,7 @@ impl TokenConvertor for Convertor { | |||
506 | 505 | ||
507 | fn peek(&self) -> Option<Self::Token> { | 506 | fn peek(&self) -> Option<Self::Token> { |
508 | if let Some((punct, mut offset)) = self.punct_offset.clone() { | 507 | if let Some((punct, mut offset)) = self.punct_offset.clone() { |
509 | offset = offset + TextSize::of('.'); | 508 | offset += TextSize::of('.'); |
510 | if usize::from(offset) < punct.text().len() { | 509 | if usize::from(offset) < punct.text().len() { |
511 | return Some(SynToken::Punch(punct, offset)); | 510 | return Some(SynToken::Punch(punct, offset)); |
512 | } | 511 | } |
@@ -634,7 +633,7 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
634 | } | 633 | } |
635 | } | 634 | } |
636 | }; | 635 | }; |
637 | self.buf += &text; | 636 | self.buf += text; |
638 | self.text_pos += TextSize::of(text); | 637 | self.text_pos += TextSize::of(text); |
639 | } | 638 | } |
640 | 639 | ||
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index 5f173f513..c788e427e 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs | |||
@@ -490,7 +490,7 @@ [email protected] | |||
490 | 490 | ||
491 | fn to_subtree(tt: &tt::TokenTree) -> &tt::Subtree { | 491 | fn to_subtree(tt: &tt::TokenTree) -> &tt::Subtree { |
492 | if let tt::TokenTree::Subtree(subtree) = tt { | 492 | if let tt::TokenTree::Subtree(subtree) = tt { |
493 | return &subtree; | 493 | return subtree; |
494 | } | 494 | } |
495 | unreachable!("It is not a subtree"); | 495 | unreachable!("It is not a subtree"); |
496 | } | 496 | } |
@@ -1846,16 +1846,17 @@ fn test_no_space_after_semi_colon() { | |||
1846 | [email protected] | 1846 | [email protected] |
1847 | [email protected] "#" | 1847 | [email protected] "#" |
1848 | [email protected] "[" | 1848 | [email protected] "[" |
1849 | [email protected] | 1849 | [email protected] |
1850 | [email protected] | 1850 | [email protected] |
1851 | [email protected] | 1851 | [email protected] |
1852 | [email protected] "cfg" | 1852 | [email protected] |
1853 | [email protected] | 1853 | [email protected] "cfg" |
1854 | [email protected] "(" | 1854 | [email protected] |
1855 | [email protected] "feature" | 1855 | [email protected] "(" |
1856 | [email protected] "=" | 1856 | [email protected] "feature" |
1857 | [email protected] "\"std\"" | 1857 | [email protected] "=" |
1858 | [email protected] ")" | 1858 | [email protected] "\"std\"" |
1859 | [email protected] ")" | ||
1859 | [email protected] "]" | 1860 | [email protected] "]" |
1860 | [email protected] "mod" | 1861 | [email protected] "mod" |
1861 | [email protected] | 1862 | [email protected] |
@@ -1865,16 +1866,17 @@ fn test_no_space_after_semi_colon() { | |||
1865 | [email protected] | 1866 | [email protected] |
1866 | [email protected] "#" | 1867 | [email protected] "#" |
1867 | [email protected] "[" | 1868 | [email protected] "[" |
1868 | [email protected] | 1869 | [email protected] |
1869 | [email protected] | 1870 | [email protected] |
1870 | [email protected] | 1871 | [email protected] |
1871 | [email protected] "cfg" | 1872 | [email protected] |
1872 | [email protected] | 1873 | [email protected] "cfg" |
1873 | [email protected] "(" | 1874 | [email protected] |
1874 | [email protected] "feature" | 1875 | [email protected] "(" |
1875 | [email protected] "=" | 1876 | [email protected] "feature" |
1876 | [email protected] "\"std\"" | 1877 | [email protected] "=" |
1877 | [email protected] ")" | 1878 | [email protected] "\"std\"" |
1879 | [email protected] ")" | ||
1878 | [email protected] "]" | 1880 | [email protected] "]" |
1879 | [email protected] "mod" | 1881 | [email protected] "mod" |
1880 | [email protected] | 1882 | [email protected] |
diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index 99a8d250b..5a4eca7bf 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs | |||
@@ -115,7 +115,7 @@ impl<'a> TtIter<'a> { | |||
115 | } | 115 | } |
116 | } | 116 | } |
117 | 117 | ||
118 | let buffer = TokenBuffer::from_tokens(&self.inner.as_slice()); | 118 | let buffer = TokenBuffer::from_tokens(self.inner.as_slice()); |
119 | let mut src = SubtreeTokenSource::new(&buffer); | 119 | let mut src = SubtreeTokenSource::new(&buffer); |
120 | let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; | 120 | let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; |
121 | 121 | ||
@@ -138,7 +138,7 @@ impl<'a> TtIter<'a> { | |||
138 | } | 138 | } |
139 | } | 139 | } |
140 | self.inner = self.inner.as_slice()[res.len()..].iter(); | 140 | self.inner = self.inner.as_slice()[res.len()..].iter(); |
141 | if res.len() == 0 && err.is_none() { | 141 | if res.is_empty() && err.is_none() { |
142 | err = Some(err!("no tokens consumed")); | 142 | err = Some(err!("no tokens consumed")); |
143 | } | 143 | } |
144 | let res = match res.len() { | 144 | let res = match res.len() { |