Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace syntax's SmallVector with AccumulateVec #37551

Merged
merged 1 commit into from
Nov 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ DEPS_serialize := std log
DEPS_term := std
DEPS_test := std getopts term native:rust_test_helpers

DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos rustc_data_structures
DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros proc_macro
DEPS_syntax_pos := serialize
DEPS_proc_macro_tokens := syntax syntax_pos log
Expand Down
1 change: 1 addition & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
{
// We use SmallVector here instead of Vec because this code is hot and
// it's rare that the stack length exceeds 1.
let mut stack = SmallVector::zero();
let mut stack = SmallVector::new();
stack.push((a_ty, dir, b_vid));
loop {
// For each turn of the loop, we extract a tuple
Expand Down
158 changes: 152 additions & 6 deletions src/librustc_data_structures/accumulate_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,68 @@
//! A vector type intended to be used for collecting from iterators onto the stack.
//!
//! Space for up to N elements is provided on the stack. If more elements are collected, Vec is
//! used to store the values on the heap. This type does not support re-allocating onto the heap,
//! and there is no way to push more elements onto the existing storage.
//! used to store the values on the heap.
//!
//! The N above is determined by Array's implementor, by way of an associatated constant.

use std::ops::Deref;
use std::iter::{IntoIterator, FromIterator};
use std::ops::{Deref, DerefMut};
use std::iter::{self, IntoIterator, FromIterator};
use std::slice;
use std::vec;

use array_vec::{Array, ArrayVec};
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

#[derive(Debug)]
use array_vec::{self, Array, ArrayVec};

#[derive(PartialEq, Eq, Hash, Debug)]
pub enum AccumulateVec<A: Array> {
Array(ArrayVec<A>),
Heap(Vec<A::Element>)
}

impl<A> Clone for AccumulateVec<A>
where A: Array,
A::Element: Clone {
fn clone(&self) -> Self {
match *self {
AccumulateVec::Array(ref arr) => AccumulateVec::Array(arr.clone()),
AccumulateVec::Heap(ref vec) => AccumulateVec::Heap(vec.clone()),
}
}
}

impl<A: Array> AccumulateVec<A> {
pub fn new() -> AccumulateVec<A> {
AccumulateVec::Array(ArrayVec::new())
}

pub fn one(el: A::Element) -> Self {
iter::once(el).collect()
}

pub fn many<I: IntoIterator<Item=A::Element>>(iter: I) -> Self {
iter.into_iter().collect()
}

pub fn len(&self) -> usize {
match *self {
AccumulateVec::Array(ref arr) => arr.len(),
AccumulateVec::Heap(ref vec) => vec.len(),
}
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}

pub fn pop(&mut self) -> Option<A::Element> {
match *self {
AccumulateVec::Array(ref mut arr) => arr.pop(),
AccumulateVec::Heap(ref mut vec) => vec.pop(),
}
}
}

impl<A: Array> Deref for AccumulateVec<A> {
type Target = [A::Element];
fn deref(&self) -> &Self::Target {
Expand All @@ -37,6 +83,15 @@ impl<A: Array> Deref for AccumulateVec<A> {
}
}

impl<A: Array> DerefMut for AccumulateVec<A> {
fn deref_mut(&mut self) -> &mut [A::Element] {
match *self {
AccumulateVec::Array(ref mut v) => &mut v[..],
AccumulateVec::Heap(ref mut v) => &mut v[..],
}
}
}

impl<A: Array> FromIterator<A::Element> for AccumulateVec<A> {
fn from_iter<I>(iter: I) -> AccumulateVec<A> where I: IntoIterator<Item=A::Element> {
let iter = iter.into_iter();
Expand All @@ -50,3 +105,94 @@ impl<A: Array> FromIterator<A::Element> for AccumulateVec<A> {
}
}

pub struct IntoIter<A: Array> {
repr: IntoIterRepr<A>,
}

enum IntoIterRepr<A: Array> {
Array(array_vec::Iter<A>),
Heap(vec::IntoIter<A::Element>),
}

impl<A: Array> Iterator for IntoIter<A> {
type Item = A::Element;

fn next(&mut self) -> Option<A::Element> {
match self.repr {
IntoIterRepr::Array(ref mut arr) => arr.next(),
IntoIterRepr::Heap(ref mut iter) => iter.next(),
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
match self.repr {
IntoIterRepr::Array(ref iter) => iter.size_hint(),
IntoIterRepr::Heap(ref iter) => iter.size_hint(),
}
}
}

impl<A: Array> IntoIterator for AccumulateVec<A> {
type Item = A::Element;
type IntoIter = IntoIter<A>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
repr: match self {
AccumulateVec::Array(arr) => IntoIterRepr::Array(arr.into_iter()),
AccumulateVec::Heap(vec) => IntoIterRepr::Heap(vec.into_iter()),
}
}
}
}

impl<'a, A: Array> IntoIterator for &'a AccumulateVec<A> {
type Item = &'a A::Element;
type IntoIter = slice::Iter<'a, A::Element>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}

impl<'a, A: Array> IntoIterator for &'a mut AccumulateVec<A> {
type Item = &'a mut A::Element;
type IntoIter = slice::IterMut<'a, A::Element>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}

impl<A: Array> From<Vec<A::Element>> for AccumulateVec<A> {
fn from(v: Vec<A::Element>) -> AccumulateVec<A> {
AccumulateVec::many(v)
}
}

impl<A: Array> Default for AccumulateVec<A> {
fn default() -> AccumulateVec<A> {
AccumulateVec::new()
}
}

impl<A> Encodable for AccumulateVec<A>
where A: Array,
A::Element: Encodable {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_seq(self.len(), |s| {
for (i, e) in self.iter().enumerate() {
try!(s.emit_seq_elt(i, |s| e.encode(s)));
}
Ok(())
})
}
}

impl<A> Decodable for AccumulateVec<A>
where A: Array,
A::Element: Decodable {
fn decode<D: Decoder>(d: &mut D) -> Result<AccumulateVec<A>, D::Error> {
d.read_seq(|d, len| {
Ok(try!((0..len).map(|i| d.read_seq_elt(i, |d| Decodable::decode(d))).collect()))
})
}
}

Loading