Make some new functions const.

This commit is contained in:
Stephen Chung 2021-11-25 17:09:00 +08:00
parent fc472f641b
commit 280b5b405e
14 changed files with 58 additions and 50 deletions

View File

@ -4,6 +4,11 @@ Rhai Release Notes
Version 1.3.0
=============
Compiler requirement
--------------------
* Minimum compiler version is 1.51.
Enhancements
------------

View File

@ -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 }

View File

@ -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

View File

@ -60,7 +60,7 @@ impl Engine {
name: impl AsRef<str>,
args: impl crate::FuncArgs,
) -> Result<T, Box<EvalAltResult>> {
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)?;

View File

@ -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());

View File

@ -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<Stmt> 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)

View File

@ -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,

View File

@ -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

View File

@ -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::<CallableFunction>::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.

View File

@ -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"))]

View File

@ -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( <EOF>
@ -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<Expr, ParseError> {
let mut settings = settings;
let mut inputs = StaticVec::<Expr>::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<Stmt>, StaticVec<Shared<ScriptFnDef>>), 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() {

View File

@ -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<String> {
self.gen_fn_metadata_with_ast_to_json(&AST::empty(), include_global)
}

View File

@ -146,7 +146,7 @@ impl TryFrom<Identifier> for FnPtr {
#[inline]
fn try_from(value: Identifier) -> Result<Self, Self::Error> {
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())
}

View File

@ -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<Box<StaticVec<Identifier>>>); SCOPE_ENTRIES_INLINED],
>,
names: SmallVec<[(Cow<'a, str>, Option<Box<StaticVec<Identifier>>>); 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());
}