@@ -40,18 +40,12 @@ fn benchmark_expand_macro_rules() {
40
40
. into_iter ( )
41
41
. map ( |( id, tt) | {
42
42
let res = rules[ & id] . expand ( & tt) ;
43
- if res. err . is_some ( ) {
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
- }
43
+ assert ! ( res. err. is_none( ) ) ;
50
44
res. value . token_trees . len ( )
51
45
} )
52
46
. sum ( )
53
47
} ;
54
- assert_eq ! ( hash, 66995 ) ;
48
+ assert_eq ! ( hash, 69413 ) ;
55
49
}
56
50
57
51
fn macro_rules_fixtures ( ) -> FxHashMap < String , MacroRules > {
@@ -77,7 +71,7 @@ fn macro_rules_fixtures_tt() -> FxHashMap<String, tt::Subtree> {
77
71
. collect ( )
78
72
}
79
73
80
- // Generate random invocation fixtures from rules
74
+ /// Generate random invocation fixtures from rules
81
75
fn invocation_fixtures ( rules : & FxHashMap < String , MacroRules > ) -> Vec < ( String , tt:: Subtree ) > {
82
76
let mut seed = 123456789 ;
83
77
let mut res = Vec :: new ( ) ;
@@ -86,11 +80,31 @@ fn invocation_fixtures(rules: &FxHashMap<String, MacroRules>) -> Vec<(String, tt
86
80
for rule in & it. rules {
87
81
// Generate twice
88
82
for _ in 0 ..2 {
89
- let mut subtree = tt:: Subtree :: default ( ) ;
90
- for op in rule. lhs . iter ( ) {
91
- collect_from_op ( op, & mut subtree, & mut seed) ;
83
+ // The input are generated by filling the `Op` randomly.
84
+ // However, there are some cases generated are ambiguous for expanding, for example:
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
}
0 commit comments