mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
reduce allocations further
This commit is contained in:
parent
b265663515
commit
c487506ab4
1 changed files with 50 additions and 20 deletions
|
@ -644,39 +644,40 @@ fn malformed_pattern(env: &mut Env, problem: MalformedPatternProblem, region: Re
|
|||
Pattern::MalformedPattern(problem, region)
|
||||
}
|
||||
|
||||
enum BindingsFromPatternWork<'a> {
|
||||
/// An iterator over the bindings made by a pattern.
|
||||
///
|
||||
/// We attempt to make no allocations when we can.
|
||||
pub enum BindingsFromPattern<'a> {
|
||||
Empty,
|
||||
One(&'a Loc<Pattern>),
|
||||
Many(Vec<BindingsFromPatternWork<'a>>),
|
||||
}
|
||||
|
||||
pub enum BindingsFromPatternWork<'a> {
|
||||
Pattern(&'a Loc<Pattern>),
|
||||
Destruct(&'a Loc<RecordDestruct>),
|
||||
}
|
||||
|
||||
pub struct BindingsFromPattern<'a> {
|
||||
stack: Vec<BindingsFromPatternWork<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> BindingsFromPattern<'a> {
|
||||
pub fn new(initial: &'a Loc<Pattern>) -> Self {
|
||||
Self {
|
||||
stack: vec![BindingsFromPatternWork::Pattern(initial)],
|
||||
}
|
||||
Self::One(initial)
|
||||
}
|
||||
|
||||
pub fn new_many<I>(it: I) -> Self
|
||||
pub fn new_many<I>(mut it: I) -> Self
|
||||
where
|
||||
I: Iterator<Item = &'a Loc<Pattern>>,
|
||||
{
|
||||
Self {
|
||||
stack: it.map(BindingsFromPatternWork::Pattern).collect(),
|
||||
if let (1, Some(1)) = it.size_hint() {
|
||||
Self::new(it.next().unwrap())
|
||||
} else {
|
||||
Self::Many(it.map(BindingsFromPatternWork::Pattern).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for BindingsFromPattern<'a> {
|
||||
type Item = (Symbol, Region);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
fn next_many(stack: &mut Vec<BindingsFromPatternWork<'a>>) -> Option<(Symbol, Region)> {
|
||||
use Pattern::*;
|
||||
|
||||
while let Some(work) = self.stack.pop() {
|
||||
while let Some(work) = stack.pop() {
|
||||
match work {
|
||||
BindingsFromPatternWork::Pattern(loc_pattern) => {
|
||||
use BindingsFromPatternWork::*;
|
||||
|
@ -695,15 +696,15 @@ impl<'a> Iterator for BindingsFromPattern<'a> {
|
|||
..
|
||||
} => {
|
||||
let it = loc_args.iter().rev().map(|(_, p)| Pattern(p));
|
||||
self.stack.extend(it);
|
||||
stack.extend(it);
|
||||
}
|
||||
UnwrappedOpaque { argument, .. } => {
|
||||
let (_, loc_arg) = &**argument;
|
||||
self.stack.push(Pattern(loc_arg));
|
||||
stack.push(Pattern(loc_arg));
|
||||
}
|
||||
RecordDestructure { destructs, .. } => {
|
||||
let it = destructs.iter().rev().map(Destruct);
|
||||
self.stack.extend(it);
|
||||
stack.extend(it);
|
||||
}
|
||||
NumLiteral(..)
|
||||
| IntLiteral(..)
|
||||
|
@ -733,6 +734,35 @@ impl<'a> Iterator for BindingsFromPattern<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for BindingsFromPattern<'a> {
|
||||
type Item = (Symbol, Region);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
use Pattern::*;
|
||||
|
||||
match self {
|
||||
BindingsFromPattern::Empty => None,
|
||||
BindingsFromPattern::One(loc_pattern) => match &loc_pattern.value {
|
||||
Identifier(symbol)
|
||||
| Shadowed(_, _, symbol)
|
||||
| AbilityMemberSpecialization {
|
||||
ident: symbol,
|
||||
specializes: _,
|
||||
} => {
|
||||
let region = loc_pattern.region;
|
||||
*self = Self::Empty;
|
||||
Some((*symbol, region))
|
||||
}
|
||||
_ => {
|
||||
*self = Self::Many(vec![BindingsFromPatternWork::Pattern(loc_pattern)]);
|
||||
self.next()
|
||||
}
|
||||
},
|
||||
BindingsFromPattern::Many(stack) => Self::next_many(stack),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flatten_str_literal(literal: &StrLiteral<'_>) -> Pattern {
|
||||
use ast::StrLiteral::*;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue