Skip to content

Commit f19f939

Browse files
authored
Rollup merge of rust-lang#37551 - Mark-Simulacrum:upgrade-accvec, r=eddyb
Replace syntax's SmallVector with AccumulateVec This adds a new type to data_structures, `SmallVec`, which wraps `AccumulateVec` with support for re-allocating onto the heap (`SmallVec::reserve`). `SmallVec` is then used to replace the implementation of `SmallVector` in libsyntax. r? @eddyb Fixes rust-lang#37371. Using `SmallVec` instead of libsyntax's `SmallVector` will provide the `N = 2/4` case easily (just needs a few more `Array` impls). cc @nnethercote, probably interested in this area
2 parents c3ab57c + 7bbebb1 commit f19f939

File tree

15 files changed

+573
-286
lines changed

15 files changed

+573
-286
lines changed

mk/crates.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ DEPS_serialize := std log
100100
DEPS_term := std
101101
DEPS_test := std getopts term native:rust_test_helpers
102102

103-
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
103+
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos rustc_data_structures
104104
DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros proc_macro
105105
DEPS_syntax_pos := serialize
106106
DEPS_proc_macro_tokens := syntax syntax_pos log

src/Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/infer/combine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
184184
{
185185
// We use SmallVector here instead of Vec because this code is hot and
186186
// it's rare that the stack length exceeds 1.
187-
let mut stack = SmallVector::zero();
187+
let mut stack = SmallVector::new();
188188
stack.push((a_ty, dir, b_vid));
189189
loop {
190190
// For each turn of the loop, we extract a tuple

src/librustc_data_structures/accumulate_vec.rs

+152-6
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,68 @@
1111
//! A vector type intended to be used for collecting from iterators onto the stack.
1212
//!
1313
//! Space for up to N elements is provided on the stack. If more elements are collected, Vec is
14-
//! used to store the values on the heap. This type does not support re-allocating onto the heap,
15-
//! and there is no way to push more elements onto the existing storage.
14+
//! used to store the values on the heap.
1615
//!
1716
//! The N above is determined by Array's implementor, by way of an associatated constant.
1817
19-
use std::ops::Deref;
20-
use std::iter::{IntoIterator, FromIterator};
18+
use std::ops::{Deref, DerefMut};
19+
use std::iter::{self, IntoIterator, FromIterator};
20+
use std::slice;
21+
use std::vec;
2122

22-
use array_vec::{Array, ArrayVec};
23+
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
2324

24-
#[derive(Debug)]
25+
use array_vec::{self, Array, ArrayVec};
26+
27+
#[derive(PartialEq, Eq, Hash, Debug)]
2528
pub enum AccumulateVec<A: Array> {
2629
Array(ArrayVec<A>),
2730
Heap(Vec<A::Element>)
2831
}
2932

33+
impl<A> Clone for AccumulateVec<A>
34+
where A: Array,
35+
A::Element: Clone {
36+
fn clone(&self) -> Self {
37+
match *self {
38+
AccumulateVec::Array(ref arr) => AccumulateVec::Array(arr.clone()),
39+
AccumulateVec::Heap(ref vec) => AccumulateVec::Heap(vec.clone()),
40+
}
41+
}
42+
}
43+
44+
impl<A: Array> AccumulateVec<A> {
45+
pub fn new() -> AccumulateVec<A> {
46+
AccumulateVec::Array(ArrayVec::new())
47+
}
48+
49+
pub fn one(el: A::Element) -> Self {
50+
iter::once(el).collect()
51+
}
52+
53+
pub fn many<I: IntoIterator<Item=A::Element>>(iter: I) -> Self {
54+
iter.into_iter().collect()
55+
}
56+
57+
pub fn len(&self) -> usize {
58+
match *self {
59+
AccumulateVec::Array(ref arr) => arr.len(),
60+
AccumulateVec::Heap(ref vec) => vec.len(),
61+
}
62+
}
63+
64+
pub fn is_empty(&self) -> bool {
65+
self.len() == 0
66+
}
67+
68+
pub fn pop(&mut self) -> Option<A::Element> {
69+
match *self {
70+
AccumulateVec::Array(ref mut arr) => arr.pop(),
71+
AccumulateVec::Heap(ref mut vec) => vec.pop(),
72+
}
73+
}
74+
}
75+
3076
impl<A: Array> Deref for AccumulateVec<A> {
3177
type Target = [A::Element];
3278
fn deref(&self) -> &Self::Target {
@@ -37,6 +83,15 @@ impl<A: Array> Deref for AccumulateVec<A> {
3783
}
3884
}
3985

86+
impl<A: Array> DerefMut for AccumulateVec<A> {
87+
fn deref_mut(&mut self) -> &mut [A::Element] {
88+
match *self {
89+
AccumulateVec::Array(ref mut v) => &mut v[..],
90+
AccumulateVec::Heap(ref mut v) => &mut v[..],
91+
}
92+
}
93+
}
94+
4095
impl<A: Array> FromIterator<A::Element> for AccumulateVec<A> {
4196
fn from_iter<I>(iter: I) -> AccumulateVec<A> where I: IntoIterator<Item=A::Element> {
4297
let iter = iter.into_iter();
@@ -50,3 +105,94 @@ impl<A: Array> FromIterator<A::Element> for AccumulateVec<A> {
50105
}
51106
}
52107

108+
pub struct IntoIter<A: Array> {
109+
repr: IntoIterRepr<A>,
110+
}
111+
112+
enum IntoIterRepr<A: Array> {
113+
Array(array_vec::Iter<A>),
114+
Heap(vec::IntoIter<A::Element>),
115+
}
116+
117+
impl<A: Array> Iterator for IntoIter<A> {
118+
type Item = A::Element;
119+
120+
fn next(&mut self) -> Option<A::Element> {
121+
match self.repr {
122+
IntoIterRepr::Array(ref mut arr) => arr.next(),
123+
IntoIterRepr::Heap(ref mut iter) => iter.next(),
124+
}
125+
}
126+
127+
fn size_hint(&self) -> (usize, Option<usize>) {
128+
match self.repr {
129+
IntoIterRepr::Array(ref iter) => iter.size_hint(),
130+
IntoIterRepr::Heap(ref iter) => iter.size_hint(),
131+
}
132+
}
133+
}
134+
135+
impl<A: Array> IntoIterator for AccumulateVec<A> {
136+
type Item = A::Element;
137+
type IntoIter = IntoIter<A>;
138+
fn into_iter(self) -> Self::IntoIter {
139+
IntoIter {
140+
repr: match self {
141+
AccumulateVec::Array(arr) => IntoIterRepr::Array(arr.into_iter()),
142+
AccumulateVec::Heap(vec) => IntoIterRepr::Heap(vec.into_iter()),
143+
}
144+
}
145+
}
146+
}
147+
148+
impl<'a, A: Array> IntoIterator for &'a AccumulateVec<A> {
149+
type Item = &'a A::Element;
150+
type IntoIter = slice::Iter<'a, A::Element>;
151+
fn into_iter(self) -> Self::IntoIter {
152+
self.iter()
153+
}
154+
}
155+
156+
impl<'a, A: Array> IntoIterator for &'a mut AccumulateVec<A> {
157+
type Item = &'a mut A::Element;
158+
type IntoIter = slice::IterMut<'a, A::Element>;
159+
fn into_iter(self) -> Self::IntoIter {
160+
self.iter_mut()
161+
}
162+
}
163+
164+
impl<A: Array> From<Vec<A::Element>> for AccumulateVec<A> {
165+
fn from(v: Vec<A::Element>) -> AccumulateVec<A> {
166+
AccumulateVec::many(v)
167+
}
168+
}
169+
170+
impl<A: Array> Default for AccumulateVec<A> {
171+
fn default() -> AccumulateVec<A> {
172+
AccumulateVec::new()
173+
}
174+
}
175+
176+
impl<A> Encodable for AccumulateVec<A>
177+
where A: Array,
178+
A::Element: Encodable {
179+
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
180+
s.emit_seq(self.len(), |s| {
181+
for (i, e) in self.iter().enumerate() {
182+
try!(s.emit_seq_elt(i, |s| e.encode(s)));
183+
}
184+
Ok(())
185+
})
186+
}
187+
}
188+
189+
impl<A> Decodable for AccumulateVec<A>
190+
where A: Array,
191+
A::Element: Decodable {
192+
fn decode<D: Decoder>(d: &mut D) -> Result<AccumulateVec<A>, D::Error> {
193+
d.read_seq(|d, len| {
194+
Ok(try!((0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect()))
195+
})
196+
}
197+
}
198+

0 commit comments

Comments
 (0)