Auto merge of #52145 - ExpHP:drop-it-like-its-eof, r=nikomatsakis
Fix macro parser quadratic complexity in small repeating groups Observed in #51754, and more easily demonstrated with the following: ```rust macro_rules! stress { ($($t:tt)+) => { }; } fn main() { stress!{ a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a // ... 65536 copies of "a" total ... a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a } } ``` which takes 50 seconds to compile prior to the fix and <1s after. I hope this has a visible impact on the compile times for real code. (I think it is most likely to affect incremental TT munchers that deal with large inputs, though it depends on how they are written) For a fuller description of the performance issue: https://github.com/rust-lang/rust/issues/51754#issuecomment-403242159 --- There is no test (yet) because I'm not sure how easily to measure this for regressions.
This commit is contained in:
commit
4f3c7a472b
@ -697,9 +697,14 @@ pub fn parse(
|
||||
return Failure(parser.span, token::Eof);
|
||||
}
|
||||
}
|
||||
// Performance hack: eof_items may share matchers via Rc with other things that we want
|
||||
// to modify. Dropping eof_items now may drop these refcounts to 1, preventing an
|
||||
// unnecessary implicit clone later in Rc::make_mut.
|
||||
drop(eof_items);
|
||||
|
||||
// Another possibility is that we need to call out to parse some rust nonterminal
|
||||
// (black-box) parser. However, if there is not EXACTLY ONE of these, something is wrong.
|
||||
else if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
|
||||
if (!bb_items.is_empty() && !next_items.is_empty()) || bb_items.len() > 1 {
|
||||
let nts = bb_items
|
||||
.iter()
|
||||
.map(|item| match item.top_elts.get_tt(item.idx) {
|
||||
|
Loading…
Reference in New Issue
Block a user