diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 139475cf..7110fd1b 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -2,6 +2,7 @@ use super::{ASTFlags, ASTNode, BinaryExpr, Expr, FnCallExpr, Ident}; use crate::engine::KEYWORD_EVAL; +use crate::func::StraightHashMap; use crate::tokenizer::Token; use crate::types::Span; use crate::{calc_fn_hash, Position, StaticVec, INT}; @@ -9,9 +10,8 @@ use crate::{calc_fn_hash, Position, StaticVec, INT}; use std::prelude::v1::*; use std::{ borrow::Borrow, - collections::BTreeMap, fmt, - hash::Hash, + hash::{Hash, Hasher}, mem, num::NonZeroUsize, ops::{Deref, DerefMut, Range, RangeInclusive}, @@ -303,18 +303,31 @@ pub type CaseBlocksList = smallvec::SmallVec<[usize; 1]>; /// _(internals)_ A type containing all cases for a `switch` statement. /// Exported under the `internals` feature only. -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub struct SwitchCasesCollection { /// List of [`ConditionalExpr`]'s. pub expressions: StaticVec, /// Dictionary mapping value hashes to [`ConditionalExpr`]'s. - pub cases: BTreeMap, + pub cases: StraightHashMap, /// List of range cases. pub ranges: StaticVec, /// Statements block for the default case (there can be no condition for the default case). pub def_case: Option, } +impl Hash for SwitchCasesCollection { + #[inline(always)] + fn hash(&self, state: &mut H) { + self.expressions.hash(state); + + self.cases.len().hash(state); + self.cases.iter().for_each(|kv| kv.hash(state)); + + self.ranges.hash(state); + self.def_case.hash(state); + } +} + /// Number of items to keep inline for [`StmtBlockContainer`]. #[cfg(not(feature = "no_std"))] const STMT_BLOCK_INLINE_SIZE: usize = 8; diff --git a/src/parser.rs b/src/parser.rs index 9f8c6e1f..0f452d8c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1121,7 +1121,7 @@ impl Engine { } let mut expressions = StaticVec::::new(); - let mut cases = BTreeMap::::new(); + let mut cases = StraightHashMap::::default(); let mut ranges = StaticVec::::new(); let mut def_case = None; let mut def_case_pos = Position::NONE;