mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Merge #7513
7513: NFA parser for mbe matcher r=matklad a=edwin0cheng Almost straight porting from rustc one, but a little bit slow :( ``` rust-analyzer analysis-stats -q . ``` From: ```log Database loaded: 636.11ms, 277minstr crates: 36, mods: 594, decls: 11527, fns: 9017 Item Collection: 10.99s, 60ginstr exprs: 249618, ??ty: 2699 (1%), ?ty: 2101 (0%), !ty: 932 Inference: 28.94s, 123ginstr Total: 39.93s, 184ginstr ``` To: ```log Database loaded: 630.90ms, 277minstr crates: 36, mods: 594, decls: 11528, fns: 9018 Item Collection: 13.70s, 77ginstr exprs: 249482, ??ty: 2699 (1%), ?ty: 2101 (0%), !ty: 932 Inference: 30.27s, 133ginstr Total: 43.97s, 211ginstr ``` Fixes #4777 Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
91bf5fa827
9 changed files with 592 additions and 175 deletions
|
@ -40,18 +40,12 @@ fn benchmark_expand_macro_rules() {
|
|||
.into_iter()
|
||||
.map(|(id, tt)| {
|
||||
let res = rules[&id].expand(&tt);
|
||||
if res.err.is_some() {
|
||||
// FIXME:
|
||||
// Currently `invocation_fixtures` will generate some correct invocations but
|
||||
// cannot be expanded by mbe. We ignore errors here.
|
||||
// See: https://github.com/rust-analyzer/rust-analyzer/issues/4777
|
||||
eprintln!("err from {} {:?}", id, res.err);
|
||||
}
|
||||
assert!(res.err.is_none());
|
||||
res.value.token_trees.len()
|
||||
})
|
||||
.sum()
|
||||
};
|
||||
assert_eq!(hash, 66995);
|
||||
assert_eq!(hash, 69413);
|
||||
}
|
||||
|
||||
fn macro_rules_fixtures() -> FxHashMap<String, MacroRules> {
|
||||
|
@ -77,7 +71,7 @@ fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
// Generate random invocation fixtures from rules
|
||||
/// Generate random invocation fixtures from rules
|
||||
fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt::Subtree)> {
|
||||
let mut seed = 123456789;
|
||||
let mut res = Vec::new();
|
||||
|
@ -86,11 +80,31 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt
|
|||
for rule in &it.rules {
|
||||
// Generate twice
|
||||
for _ in 0..2 {
|
||||
let mut subtree = tt::Subtree::default();
|
||||
for op in rule.lhs.iter() {
|
||||
collect_from_op(op, &mut subtree, &mut seed);
|
||||
// The input are generated by filling the `Op` randomly.
|
||||
// However, there are some cases generated are ambiguous for expanding, for example:
|
||||
// ```rust
|
||||
// macro_rules! m {
|
||||
// ($($t:ident),* as $ty:ident) => {}
|
||||
// }
|
||||
// m!(as u32); // error: local ambiguity: multiple parsing options: built-in NTs ident ('t') or 1 other option.
|
||||
// ```
|
||||
//
|
||||
// So we just skip any error cases and try again
|
||||
let mut try_cnt = 0;
|
||||
loop {
|
||||
let mut subtree = tt::Subtree::default();
|
||||
for op in rule.lhs.iter() {
|
||||
collect_from_op(op, &mut subtree, &mut seed);
|
||||
}
|
||||
if it.expand(&subtree).err.is_none() {
|
||||
res.push((name.clone(), subtree));
|
||||
break;
|
||||
}
|
||||
try_cnt += 1;
|
||||
if try_cnt > 100 {
|
||||
panic!("invocaton fixture {} cannot be generated.\n", name);
|
||||
}
|
||||
}
|
||||
res.push((name.clone(), subtree));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue