From 280b5b405edb6d719049a8a87b3de6c427fe2a1b Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 25 Nov 2021 17:09:00 +0800 Subject: [PATCH] Make some new functions const. --- CHANGELOG.md | 5 +++++ Cargo.toml | 2 +- README.md | 2 +- src/api/call_fn.rs | 2 +- src/api/mod.rs | 2 +- src/ast.rs | 14 +++++++------- src/engine.rs | 14 +++++++------- src/func/call.rs | 2 +- src/module/mod.rs | 6 +++--- src/optimizer.rs | 8 ++++---- src/parser.rs | 32 ++++++++++++++++---------------- src/serde/metadata.rs | 1 + src/types/fn_ptr.rs | 2 +- src/types/scope.rs | 16 +++++++++------- 14 files changed, 58 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddfcdd85..82227921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ Rhai Release Notes Version 1.3.0 ============= +Compiler requirement +-------------------- + +* Minimum compiler version is 1.51. + Enhancements ------------ diff --git a/Cargo.toml b/Cargo.toml index de6a89d5..11012109 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["scripting", "scripting-engine", "scripting-language", "embedded"] categories = ["no-std", "embedded", "wasm", "parser-implementations"] [dependencies] -smallvec = { version = "1.6", default-features = false, features = ["union"] } +smallvec = { version = "1.7", default-features = false, features = ["union", "const_new" ] } ahash = { version = "0.7", default-features = false } num-traits = { version = "0.2", default-features = false } smartstring = { version = "0.2.7", default-features = false } diff --git a/README.md b/README.md index 7aa96bfb..d5680e45 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Targets and builds * All CPU and O/S targets supported by Rust, including: * WebAssembly (WASM) * `no-std` -* Minimum Rust version 1.49 +* Minimum Rust version 1.51 Standard features diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 61309f18..6ebb35df 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -60,7 +60,7 @@ impl Engine { name: impl AsRef, args: impl crate::FuncArgs, ) -> Result> { - let mut arg_values = crate::StaticVec::new(); + let mut arg_values = crate::StaticVec::new_const(); args.parse(&mut arg_values); let result = self.call_fn_raw(scope, ast, true, true, name, None, arg_values)?; diff --git a/src/api/mod.rs b/src/api/mod.rs index 4e9d7330..5062496c 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -90,7 +90,7 @@ impl Engine { .collect(); #[cfg(feature = "no_function")] - let lib = crate::StaticVec::new(); + let lib = crate::StaticVec::new_const(); let statements = std::mem::take(ast.statements_mut()); diff --git a/src/ast.rs b/src/ast.rs index 2e2caabc..bca05835 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -228,7 +228,7 @@ impl AST { pub fn empty() -> Self { Self { source: None, - body: StmtBlock::empty(), + body: StmtBlock::empty(Position::NONE), functions: Module::new().into(), #[cfg(not(feature = "no_module"))] resolver: None, @@ -401,7 +401,7 @@ impl AST { functions.merge_filtered(&self.functions, &filter); Self { source: self.source.clone(), - body: StmtBlock::empty(), + body: StmtBlock::empty(Position::NONE), functions: functions.into(), #[cfg(not(feature = "no_module"))] resolver: self.resolver.clone(), @@ -597,7 +597,7 @@ impl AST { } (false, true) => body.clone(), (true, false) => other.body.clone(), - (true, true) => StmtBlock::empty(), + (true, true) => StmtBlock::empty(Position::NONE), }; let source = other.source.clone().or_else(|| self.source.clone()); @@ -744,7 +744,7 @@ impl AST { /// Clear all statements in the [`AST`], leaving only function definitions. #[inline(always)] pub fn clear_statements(&mut self) -> &mut Self { - self.body = StmtBlock::empty(); + self.body = StmtBlock::empty(Position::NONE); self } /// Extract all top-level literal constant and/or variable definitions. @@ -997,8 +997,8 @@ impl StmtBlock { /// Create an empty [`StmtBlock`]. #[inline(always)] #[must_use] - pub fn empty() -> Self { - Default::default() + pub const fn empty(pos: Position) -> Self { + Self(StaticVec::new_const(), pos) } /// Is this statements block empty? #[inline(always)] @@ -1306,7 +1306,7 @@ impl From for StmtBlock { fn from(stmt: Stmt) -> Self { match stmt { Stmt::Block(mut block, pos) => Self(block.iter_mut().map(mem::take).collect(), pos), - Stmt::Noop(pos) => Self(StaticVec::new(), pos), + Stmt::Noop(pos) => Self(StaticVec::new_const(), pos), _ => { let pos = stmt.position(); Self(vec![stmt].into(), pos) diff --git a/src/engine.rs b/src/engine.rs index dd1337e0..01ddc4f4 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -87,10 +87,10 @@ impl Imports { /// Create a new stack of imported [modules][Module]. #[inline(always)] #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self { - keys: StaticVec::new(), - modules: StaticVec::new(), + keys: StaticVec::new_const(), + modules: StaticVec::new_const(), source: None, num_operations: 0, num_modules: 0, @@ -784,11 +784,11 @@ impl EvalState { /// Create a new [`EvalState`]. #[inline(always)] #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self { always_search_scope: false, scope_level: 0, - fn_resolution_caches: StaticVec::new(), + fn_resolution_caches: StaticVec::new_const(), } } /// Is the state currently at global (root) level? @@ -1137,7 +1137,7 @@ impl Engine { #[must_use] pub fn new_raw() -> Self { let mut engine = Self { - global_modules: StaticVec::new(), + global_modules: StaticVec::new_const(), global_sub_modules: BTreeMap::new(), #[cfg(not(feature = "no_module"))] @@ -1845,7 +1845,7 @@ impl Engine { _ => unreachable!("index or dot chain expected, but gets {:?}", expr), }; - let idx_values = &mut StaticVec::new(); + let idx_values = &mut StaticVec::new_const(); self.eval_dot_index_chain_arguments( scope, mods, state, lib, this_ptr, rhs, term, chain_type, idx_values, 0, level, diff --git a/src/func/call.rs b/src/func/call.rs index cbd05524..f8eacb96 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -1091,7 +1091,7 @@ impl Engine { ) -> RhaiResult { let mut a_expr = args_expr; let mut total_args = a_expr.len(); - let mut curry = StaticVec::new(); + let mut curry = StaticVec::new_const(); let mut name = fn_name; let mut hashes = hashes; let redirected; // Handle call() - Redirect function call diff --git a/src/module/mod.rs b/src/module/mod.rs index c0d86696..d9da37a3 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -480,7 +480,7 @@ impl Module { namespace: FnNamespace::Internal, access: fn_def.access, params: num_params, - param_types: StaticVec::new(), + param_types: StaticVec::new_const(), #[cfg(feature = "metadata")] param_names, func: Into::::into(fn_def).into(), @@ -1729,10 +1729,10 @@ impl NamespaceRef { /// Create a new [`NamespaceRef`]. #[inline(always)] #[must_use] - pub fn new() -> Self { + pub const fn new() -> Self { Self { index: None, - path: StaticVec::new(), + path: StaticVec::new_const(), } } /// Get the [`Scope`][crate::Scope] index offset. diff --git a/src/optimizer.rs b/src/optimizer.rs index 1ac33788..af1740cd 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -67,14 +67,14 @@ struct OptimizerState<'a> { impl<'a> OptimizerState<'a> { /// Create a new State. #[inline(always)] - pub fn new( + pub const fn new( engine: &'a Engine, lib: &'a [&'a Module], optimization_level: OptimizationLevel, ) -> Self { Self { changed: false, - variables: StaticVec::new(), + variables: StaticVec::new_const(), propagate_constants: true, engine, lib, @@ -942,7 +942,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { state.set_dirty(); let fn_ptr = FnPtr::new_unchecked( fn_name.as_str_ref().expect("`ImmutableString`").into(), - StaticVec::new() + StaticVec::new_const() ); *expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos); } @@ -1140,7 +1140,7 @@ pub fn optimize_into_ast( .map(|fn_def| crate::ast::ScriptFnDef { name: fn_def.name.clone(), access: fn_def.access, - body: crate::ast::StmtBlock::empty(), + body: crate::ast::StmtBlock::empty(Position::NONE), params: fn_def.params.clone(), lib: None, #[cfg(not(feature = "no_module"))] diff --git a/src/parser.rs b/src/parser.rs index e311e2ea..279e2593 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -134,10 +134,10 @@ impl<'e> ParseState<'e> { #[cfg(not(feature = "no_closure"))] allow_capture: true, interned_strings: IdentifierBuilder::new(), - stack: StaticVec::new(), + stack: StaticVec::new_const(), entry_stack_len: 0, #[cfg(not(feature = "no_module"))] - modules: StaticVec::new(), + modules: StaticVec::new_const(), } } @@ -465,7 +465,7 @@ fn parse_fn_call( let (token, token_pos) = input.peek().expect(NEVER_ENDS); let mut namespace = namespace; - let mut args = StaticVec::new(); + let mut args = StaticVec::new_const(); match token { // id( @@ -766,7 +766,7 @@ fn parse_array_literal( let mut settings = settings; settings.pos = eat_token(input, Token::LeftBracket); - let mut arr = StaticVec::new(); + let mut arr = StaticVec::new_const(); loop { const MISSING_RBRACKET: &str = "to end this array literal"; @@ -1510,7 +1510,7 @@ fn parse_unary( // Call negative function expr => { - let mut args = StaticVec::new(); + let mut args = StaticVec::new_const(); args.push(expr); args.shrink_to_fit(); @@ -1536,7 +1536,7 @@ fn parse_unary( // Call plus function expr => { - let mut args = StaticVec::new(); + let mut args = StaticVec::new_const(); args.push(expr); args.shrink_to_fit(); @@ -1553,7 +1553,7 @@ fn parse_unary( // !expr Token::Bang => { let pos = eat_token(input, Token::Bang); - let mut args = StaticVec::new(); + let mut args = StaticVec::new_const(); args.push(parse_unary(input, state, lib, settings.level_up())?); args.shrink_to_fit(); @@ -1900,7 +1900,7 @@ fn parse_binary_op( ..Default::default() }; - let mut args = StaticVec::new(); + let mut args = StaticVec::new_const(); args.push(root); args.push(rhs); args.shrink_to_fit(); @@ -2006,8 +2006,8 @@ fn parse_custom_syntax( ) -> Result { let mut settings = settings; let mut inputs = StaticVec::::new(); - let mut segments = StaticVec::new(); - let mut tokens = StaticVec::new(); + let mut segments = StaticVec::new_const(); + let mut tokens = StaticVec::new_const(); // Adjust the variables stack if syntax.scope_may_be_changed { @@ -2992,7 +2992,7 @@ fn parse_fn( (_, pos) => return Err(PERR::FnMissingParams(name.to_string()).into_err(*pos)), }; - let mut params = StaticVec::new(); + let mut params = StaticVec::new_const(); if !match_token(input, Token::RightParen).0 { let sep_err = format!("to separate the parameters of function '{}'", name); @@ -3119,7 +3119,7 @@ fn parse_anon_fn( settings.ensure_level_within_max_limit(state.max_expr_depth)?; let mut settings = settings; - let mut params_list = StaticVec::new(); + let mut params_list = StaticVec::new_const(); if input.next().expect(NEVER_ENDS).0 != Token::Or && !match_token(input, Token::Pipe).0 { loop { @@ -3205,7 +3205,7 @@ fn parse_anon_fn( comments: None, }; - let fn_ptr = crate::FnPtr::new_unchecked(fn_name, StaticVec::new()); + let fn_ptr = crate::FnPtr::new_unchecked(fn_name, StaticVec::new_const()); let expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), settings.pos); #[cfg(not(feature = "no_closure"))] @@ -3249,7 +3249,7 @@ impl Engine { } } - let mut statements = StaticVec::new(); + let mut statements = StaticVec::new_const(); statements.push(Stmt::Expr(expr)); #[cfg(not(feature = "no_optimize"))] @@ -3257,7 +3257,7 @@ impl Engine { self, _scope, statements, - StaticVec::new(), + StaticVec::new_const(), optimization_level, )); @@ -3271,7 +3271,7 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, ) -> Result<(StaticVec, StaticVec>), ParseError> { - let mut statements = StaticVec::new(); + let mut statements = StaticVec::new_const(); let mut functions = BTreeMap::new(); while !input.peek().expect(NEVER_ENDS).0.is_eof() { diff --git a/src/serde/metadata.rs b/src/serde/metadata.rs index ee3e4b9e..83be1d86 100644 --- a/src/serde/metadata.rs +++ b/src/serde/metadata.rs @@ -278,6 +278,7 @@ impl Engine { /// 1) Functions registered into the global namespace /// 2) Functions in static modules /// 3) Functions in global modules (optional) + #[inline(always)] pub fn gen_fn_metadata_to_json(&self, include_global: bool) -> serde_json::Result { self.gen_fn_metadata_with_ast_to_json(&AST::empty(), include_global) } diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index 7e2de87c..fd4e01fe 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -146,7 +146,7 @@ impl TryFrom for FnPtr { #[inline] fn try_from(value: Identifier) -> Result { if is_valid_identifier(value.chars()) { - Ok(Self(value, StaticVec::new())) + Ok(Self(value, StaticVec::new_const())) } else { Err(EvalAltResult::ErrorFunctionNotFound(value.to_string(), Position::NONE).into()) } diff --git a/src/types/scope.rs b/src/types/scope.rs index b6eae95b..09fbdc6b 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -2,6 +2,7 @@ use super::dynamic::{AccessMode, Variant}; use crate::{Dynamic, Identifier, StaticVec}; +use smallvec::SmallVec; use std::iter::FromIterator; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -55,11 +56,9 @@ const SCOPE_ENTRIES_INLINED: usize = 8; #[derive(Debug, Clone, Hash, Default)] pub struct Scope<'a> { /// Current value of the entry. - values: smallvec::SmallVec<[Dynamic; SCOPE_ENTRIES_INLINED]>, + values: SmallVec<[Dynamic; SCOPE_ENTRIES_INLINED]>, /// (Name, aliases) of the entry. - names: smallvec::SmallVec< - [(Cow<'a, str>, Option>>); SCOPE_ENTRIES_INLINED], - >, + names: SmallVec<[(Cow<'a, str>, Option>>); SCOPE_ENTRIES_INLINED]>, } impl<'a> IntoIterator for Scope<'a> { @@ -92,8 +91,11 @@ impl<'a> Scope<'a> { /// ``` #[inline(always)] #[must_use] - pub fn new() -> Self { - Default::default() + pub const fn new() -> Self { + Self { + values: SmallVec::new_const(), + names: SmallVec::new_const(), + } } /// Empty the [`Scope`]. /// @@ -506,7 +508,7 @@ impl<'a> Scope<'a> { let (_, aliases) = self.names.get_mut(index).expect("valid index"); match aliases { None => { - let mut list = StaticVec::new(); + let mut list = StaticVec::new_const(); list.push(alias); *aliases = Some(list.into()); }