Skip to content

Commit f72685f

Browse files
committed
Use SmallVec for TypeWalker's stack.
The change also adds the missing `SmallVec::truncate` method.
1 parent 80a95e3 commit f72685f

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

src/librustc/ty/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use syntax::symbol::{Symbol, InternedString};
4848
use syntax_pos::{DUMMY_SP, Span};
4949

5050
use rustc_const_math::ConstInt;
51+
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
5152

5253
use hir;
5354
use hir::itemlikevisit::ItemLikeVisitor;
@@ -1887,7 +1888,7 @@ impl<'tcx> TyS<'tcx> {
18871888
/// Iterator that walks the immediate children of `self`. Hence
18881889
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
18891890
/// (but not `i32`, like `walk`).
1890-
pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
1891+
pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> {
18911892
walk::walk_shallow(self)
18921893
}
18931894

src/librustc/ty/walk.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,22 @@
1212
//! WARNING: this does not keep track of the region depth.
1313
1414
use ty::{self, Ty};
15-
use std::iter::Iterator;
16-
use std::vec::IntoIter;
15+
use rustc_data_structures::small_vec::SmallVec;
16+
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
17+
18+
// The TypeWalker's stack is hot enough that it's worth going to some effort to
19+
// avoid heap allocations.
20+
pub type TypeWalkerArray<'tcx> = [Ty<'tcx>; 8];
21+
pub type TypeWalkerStack<'tcx> = SmallVec<TypeWalkerArray<'tcx>>;
1722

1823
pub struct TypeWalker<'tcx> {
19-
stack: Vec<Ty<'tcx>>,
24+
stack: TypeWalkerStack<'tcx>,
2025
last_subtree: usize,
2126
}
2227

2328
impl<'tcx> TypeWalker<'tcx> {
2429
pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
25-
TypeWalker { stack: vec![ty], last_subtree: 1, }
30+
TypeWalker { stack: SmallVec::one(ty), last_subtree: 1, }
2631
}
2732

2833
/// Skips the subtree of types corresponding to the last type
@@ -61,8 +66,8 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
6166
}
6267
}
6368

64-
pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
65-
let mut stack = vec![];
69+
pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter<TypeWalkerArray<'tcx>> {
70+
let mut stack = SmallVec::new();
6671
push_subtypes(&mut stack, ty);
6772
stack.into_iter()
6873
}
@@ -73,7 +78,7 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
7378
// known to be significant to any code, but it seems like the
7479
// natural order one would expect (basically, the order of the
7580
// types as they are written).
76-
fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
81+
fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
7782
match parent_ty.sty {
7883
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
7984
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => {
@@ -112,7 +117,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
112117
}
113118
}
114119

115-
fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
120+
fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
116121
stack.push(sig.0.output);
117122
stack.extend(sig.0.inputs.iter().cloned().rev());
118123
}

src/librustc_data_structures/small_vec.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ impl<A: Array> SmallVec<A> {
130130
self.set_len(len + 1);
131131
}
132132
}
133+
134+
pub fn truncate(&mut self, len: usize) {
135+
unsafe {
136+
while len < self.len() {
137+
// Decrement len before the drop_in_place(), so a panic on Drop
138+
// doesn't re-drop the just-failed value.
139+
let newlen = self.len() - 1;
140+
self.set_len(newlen);
141+
::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
142+
}
143+
}
144+
}
133145
}
134146

135147
impl<A: Array> Deref for SmallVec<A> {

0 commit comments

Comments
 (0)