Skip to content

Commit 368c71b

Browse files
committed
Cache pat_constructors invocations
1 parent c956c65 commit 368c71b

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ use syntax_pos::{Span, DUMMY_SP};
248248
use arena::TypedArena;
249249

250250
use smallvec::{smallvec, SmallVec};
251+
use std::cell::RefCell;
251252
use std::cmp::{self, max, min, Ordering};
252253
use std::convert::TryInto;
253254
use std::fmt;
@@ -339,6 +340,9 @@ impl PatternFolder<'tcx> for LiteralExpander<'tcx> {
339340
#[derive(Debug, Clone)]
340341
pub struct PatStack<'p, 'tcx> {
341342
patterns: SmallVec<[&'p Pat<'tcx>; 2]>,
343+
// This caches the invocation of `pat_constructors` on the head of the stack. We avoid mutating
344+
// `self` to be sure we don't keep an invalid cache around.
345+
head_ctors_cache: RefCell<Option<SmallVec<[Constructor<'tcx>; 1]>>>,
342346
}
343347

344348
impl<'p, 'tcx> PatStack<'p, 'tcx> {
@@ -351,7 +355,7 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
351355
}
352356

353357
fn from_vec(vec: SmallVec<[&'p Pat<'tcx>; 2]>) -> Self {
354-
PatStack { patterns: vec }
358+
PatStack { patterns: vec, head_ctors_cache: RefCell::new(None) }
355359
}
356360

357361
fn from_slice(s: &[&'p Pat<'tcx>]) -> Self {
@@ -371,7 +375,18 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
371375
}
372376

373377
fn head_ctors(&self, cx: &MatchCheckCtxt<'_, 'tcx>) -> SmallVec<[Constructor<'tcx>; 1]> {
374-
pat_constructors(cx.tcx, cx.param_env, self.head())
378+
let new_ctors = pat_constructors(cx.tcx, cx.param_env, self.head());
379+
let borrow = self.head_ctors_cache.borrow();
380+
match *borrow {
381+
Some(ref cached_ctors) => {
382+
assert_eq!(cached_ctors, &new_ctors);
383+
}
384+
None => {
385+
drop(borrow);
386+
*self.head_ctors_cache.borrow_mut() = Some(new_ctors.clone());
387+
}
388+
}
389+
new_ctors
375390
}
376391

377392
fn iter(&self) -> impl Iterator<Item = &Pat<'tcx>> {
@@ -392,9 +407,10 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
392407
let new_heads = specialize_one_pattern(cx, self.head(), constructor, ctor_wild_subpatterns);
393408
let result = new_heads
394409
.into_iter()
395-
.map(|mut new_head| {
396-
new_head.patterns.extend_from_slice(&self.patterns[1..]);
397-
new_head
410+
.map(|new_head| {
411+
let mut pats = new_head.patterns;
412+
pats.extend_from_slice(&self.patterns[1..]);
413+
PatStack::from_vec(pats)
398414
})
399415
.collect();
400416
debug!("specialize({:#?}, {:#?}) = {:#?}", self, constructor, result);

0 commit comments

Comments
 (0)