From d5b427fda14e550954f6a5e58fd856a7369faeeb Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 12 Dec 2023 16:02:20 +0800 Subject: [PATCH] Use more ThinVec. --- Cargo.toml | 2 +- src/ast/stmt.rs | 5 +++-- src/eval/debugger.rs | 9 +++++---- src/packages/debugging.rs | 6 +++++- src/parser.rs | 20 +++++++++++--------- src/serde/metadata.rs | 31 ++++++++++++++++--------------- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a7f447f7e..b95651ecd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,7 @@ sync = [] ## Add support for the [`Decimal`](https://crates.io/crates/rust_decimal) data type (acts as the system floating-point type under `no_float`). decimal = ["rust_decimal"] ## Enable serialization/deserialization of Rhai data types via [`serde`](https://crates.io/crates/serde). -serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] +serde = ["dep:serde", "smartstring/serde", "smallvec/serde", "thin-vec/serde"] ## Allow [Unicode Standard Annex #31](https://unicode.org/reports/tr31/) for identifiers. unicode-xid-ident = ["unicode-xid"] ## Enable functions metadata (including doc-comments); implies [`serde`](#feature-serde). diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 928268aab..c73ee5493 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -17,6 +17,7 @@ use std::{ num::NonZeroUsize, ops::{Range, RangeInclusive}, }; +use thin_vec::ThinVec; /// _(internals)_ An op-assignment operator. /// Exported under the `internals` feature only. @@ -379,11 +380,11 @@ pub type CaseBlocksList = smallvec::SmallVec<[usize; 2]>; #[derive(Debug, Clone)] pub struct SwitchCasesCollection { /// List of [`ConditionalExpr`]'s. - pub expressions: Vec, + pub expressions: ThinVec, /// Dictionary mapping value hashes to [`ConditionalExpr`]'s. pub cases: StraightHashMap, /// List of range cases. - pub ranges: Vec, + pub ranges: ThinVec, /// Statements block for the default case (there can be no condition for the default case). pub def_case: Option, } diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index 49a8a50ee..fb2a576eb 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -7,6 +7,7 @@ use crate::{Dynamic, Engine, EvalAltResult, ImmutableString, Position, RhaiResul #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{fmt, iter::repeat, mem}; +use thin_vec::ThinVec; /// Callback function to initialize the debugger. #[cfg(not(feature = "sync"))] @@ -216,7 +217,7 @@ pub struct CallStackFrame { /// Function name. pub fn_name: ImmutableString, /// Copies of function call arguments, if any. - pub args: Vec, + pub args: ThinVec, /// Source of the function. pub source: Option, /// [Position][`Position`] of the function call. @@ -252,7 +253,7 @@ pub struct Debugger { /// The current set of break-points. break_points: Vec, /// The current function call stack. - call_stack: Vec, + call_stack: ThinVec, /// The current state. state: Dynamic, } @@ -261,11 +262,11 @@ impl Debugger { /// Create a new [`Debugger`]. #[inline(always)] #[must_use] - pub const fn new(status: DebuggerStatus) -> Self { + pub fn new(status: DebuggerStatus) -> Self { Self { status, break_points: Vec::new(), - call_stack: Vec::new(), + call_stack: ThinVec::new(), state: Dynamic::UNIT, } } diff --git a/src/packages/debugging.rs b/src/packages/debugging.rs index e739f1920..ce15f457e 100644 --- a/src/packages/debugging.rs +++ b/src/packages/debugging.rs @@ -59,12 +59,16 @@ mod debugging_functions { #[cfg(not(feature = "no_object"))] { use crate::INT; + use std::iter::FromIterator; let mut map = Map::new(); map.insert("display".into(), display.into()); map.insert("fn_name".into(), _fn_name.into()); if !_args.is_empty() { - map.insert("args".into(), Dynamic::from_array(_args.clone())); + map.insert( + "args".into(), + Dynamic::from_iter(_args.iter().cloned()), + ); } if let Some(source) = _source { map.insert("source".into(), source.into()); diff --git a/src/parser.rs b/src/parser.rs index a9da6d097..29966bc26 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -68,7 +68,7 @@ pub struct ParseState<'e, 's> { pub frame_pointer: usize, /// Tracks a list of external variables (variables that are not explicitly declared in the scope). #[cfg(not(feature = "no_closure"))] - pub external_vars: Vec, + pub external_vars: ThinVec, /// An indicator that, when set to `false`, disables variable capturing into externals one /// single time up until the nearest consumed Identifier token. /// @@ -79,10 +79,10 @@ pub struct ParseState<'e, 's> { pub allow_capture: bool, /// Encapsulates a local stack with imported [module][crate::Module] names. #[cfg(not(feature = "no_module"))] - pub imports: Vec, + pub imports: ThinVec, /// List of globally-imported [module][crate::Module] names. #[cfg(not(feature = "no_module"))] - pub global_imports: Vec, + pub global_imports: ThinVec, } impl fmt::Debug for ParseState<'_, '_> { @@ -123,7 +123,7 @@ impl<'e, 's> ParseState<'e, 's> { tokenizer_control, expr_filter: |_| true, #[cfg(not(feature = "no_closure"))] - external_vars: Vec::new(), + external_vars: ThinVec::new(), allow_capture: true, interned_strings, external_constants, @@ -131,9 +131,9 @@ impl<'e, 's> ParseState<'e, 's> { stack: Scope::new(), frame_pointer: 0, #[cfg(not(feature = "no_module"))] - imports: Vec::new(), + imports: ThinVec::new(), #[cfg(not(feature = "no_module"))] - global_imports: Vec::new(), + global_imports: ThinVec::new(), } } @@ -1161,9 +1161,9 @@ impl Engine { } } - let mut expressions = Vec::::new(); + let mut expressions = ThinVec::::new(); let mut cases = StraightHashMap::::default(); - let mut ranges = Vec::::new(); + let mut ranges = ThinVec::::new(); let mut def_case = None; let mut def_case_pos = Position::NONE; @@ -3795,6 +3795,8 @@ impl Engine { settings: ParseSettings, _parent: &mut ParseState, ) -> ParseResult<(Expr, Shared)> { + use core::iter::FromIterator; + let settings = settings.level_up()?; let mut params_list = StaticVec::::new_const(); @@ -3850,7 +3852,7 @@ impl Engine { FnArgsVec::new_const(), ) } else { - let externals: FnArgsVec<_> = state.external_vars.clone().into(); + let externals = FnArgsVec::from_iter(state.external_vars.iter().cloned()); let mut params = FnArgsVec::with_capacity(params_list.len() + externals.len()); params.extend(externals.iter().map(|Ident { name, .. }| name.clone())); diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index 97ce65e17..60def14b2 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{borrow::Cow, cmp::Ordering, collections::BTreeMap}; +use thin_vec::ThinVec; #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -31,8 +32,8 @@ struct FnParam<'a> { struct CustomTypeMetadata<'a> { pub type_name: &'a str, pub display_name: &'a str, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub doc_comments: Vec<&'a str>, + #[serde(default, skip_serializing_if = "ThinVec::is_empty")] + pub doc_comments: ThinVec<&'a str>, } impl PartialOrd for CustomTypeMetadata<'_> { @@ -77,13 +78,13 @@ struct FnMetadata<'a> { #[serde(default, skip_serializing_if = "Option::is_none")] pub this_type: Option<&'a str>, pub num_params: usize, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub params: Vec>, + #[serde(default, skip_serializing_if = "ThinVec::is_empty")] + pub params: ThinVec>, #[serde(default, skip_serializing_if = "str::is_empty")] pub return_type: Cow<'a, str>, pub signature: SmartString, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub doc_comments: Vec<&'a str>, + #[serde(default, skip_serializing_if = "ThinVec::is_empty")] + pub doc_comments: ThinVec<&'a str>, } impl PartialOrd for FnMetadata<'_> { @@ -166,22 +167,22 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> { struct ModuleMetadata<'a> { #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub modules: BTreeMap<&'a str, Self>, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub custom_types: Vec>, - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub functions: Vec>, + #[serde(default, skip_serializing_if = "ThinVec::is_empty")] + pub custom_types: ThinVec>, + #[serde(default, skip_serializing_if = "ThinVec::is_empty")] + pub functions: ThinVec>, #[serde(default, skip_serializing_if = "str::is_empty")] pub doc: &'a str, } impl ModuleMetadata<'_> { #[inline(always)] - pub const fn new() -> Self { + pub fn new() -> Self { Self { doc: "", modules: BTreeMap::new(), - custom_types: Vec::new(), - functions: Vec::new(), + custom_types: ThinVec::new(), + functions: ThinVec::new(), } } } @@ -196,10 +197,10 @@ impl<'a> From<&'a crate::Module> for ModuleMetadata<'a> { let mut custom_types = module .iter_custom_types() .map(Into::into) - .collect::>(); + .collect::>(); custom_types.sort(); - let mut functions = module.iter_fn().map(Into::into).collect::>(); + let mut functions = module.iter_fn().map(Into::into).collect::>(); functions.sort(); Self {