diff options
Diffstat (limited to 'crates/mbe/src/benchmark.rs')
-rw-r--r-- | crates/mbe/src/benchmark.rs | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/crates/mbe/src/benchmark.rs b/crates/mbe/src/benchmark.rs index 6d81be880..503ad1355 100644 --- a/crates/mbe/src/benchmark.rs +++ b/crates/mbe/src/benchmark.rs | |||
@@ -40,18 +40,12 @@ fn benchmark_expand_macro_rules() { | |||
40 | .into_iter() | 40 | .into_iter() |
41 | .map(|(id, tt)| { | 41 | .map(|(id, tt)| { |
42 | let res = rules[&id].expand(&tt); | 42 | let res = rules[&id].expand(&tt); |
43 | if res.err.is_some() { | 43 | assert!(res.err.is_none()); |
44 | // FIXME: | ||
45 | // Currently `invocation_fixtures` will generate some correct invocations but | ||
46 | // cannot be expanded by mbe. We ignore errors here. | ||
47 | // See: https://github.com/rust-analyzer/rust-analyzer/issues/4777 | ||
48 | eprintln!("err from {} {:?}", id, res.err); | ||
49 | } | ||
50 | res.value.token_trees.len() | 44 | res.value.token_trees.len() |
51 | }) | 45 | }) |
52 | .sum() | 46 | .sum() |
53 | }; | 47 | }; |
54 | assert_eq!(hash, 66995); | 48 | assert_eq!(hash, 69413); |
55 | } | 49 | } |
56 | 50 | ||
57 | fn macro_rules_fixtures() -> FxHashMap<String, MacroRules> { | 51 | fn macro_rules_fixtures() -> FxHashMap<String, MacroRules> { |
@@ -77,7 +71,7 @@ fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree> { | |||
77 | .collect() | 71 | .collect() |
78 | } | 72 | } |
79 | 73 | ||
80 | // Generate random invocation fixtures from rules | 74 | /// Generate random invocation fixtures from rules |
81 | fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt::Subtree)> { | 75 | fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt::Subtree)> { |
82 | let mut seed = 123456789; | 76 | let mut seed = 123456789; |
83 | let mut res = Vec::new(); | 77 | let mut res = Vec::new(); |
@@ -86,11 +80,31 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt | |||
86 | for rule in &it.rules { | 80 | for rule in &it.rules { |
87 | // Generate twice | 81 | // Generate twice |
88 | for _ in 0..2 { | 82 | for _ in 0..2 { |
89 | let mut subtree = tt::Subtree::default(); | 83 | // The input are generated by filling the `Op` randomly. |
90 | for op in rule.lhs.iter() { | 84 | // However, there are some cases generated are ambiguous for expanding, for example: |
91 | collect_from_op(op, &mut subtree, &mut seed); | 85 | // ```rust |
86 | // macro_rules! m { | ||
87 | // ($($t:ident),* as $ty:ident) => {} | ||
88 | // } | ||
89 | // m!(as u32); // error: local ambiguity: multiple parsing options: built-in NTs ident ('t') or 1 other option. | ||
90 | // ``` | ||
91 | // | ||
92 | // So we just skip any error cases and try again | ||
93 | let mut try_cnt = 0; | ||
94 | loop { | ||
95 | let mut subtree = tt::Subtree::default(); | ||
96 | for op in rule.lhs.iter() { | ||
97 | collect_from_op(op, &mut subtree, &mut seed); | ||
98 | } | ||
99 | if it.expand(&subtree).err.is_none() { | ||
100 | res.push((name.clone(), subtree)); | ||
101 | break; | ||
102 | } | ||
103 | try_cnt += 1; | ||
104 | if try_cnt > 100 { | ||
105 | panic!("invocaton fixture {} cannot be generated.\n", name); | ||
106 | } | ||
92 | } | 107 | } |
93 | res.push((name.clone(), subtree)); | ||
94 | } | 108 | } |
95 | } | 109 | } |
96 | } | 110 | } |