Satisfy Clippy.
This commit is contained in:
parent
2c73d403f7
commit
31292e683d
@ -1,3 +1,3 @@
|
|||||||
//! This file is automatically recreated during build time by `build.rs` from `build.template`.
|
//! This file is automatically recreated during build time by `build.rs` from `build.template`.
|
||||||
|
|
||||||
pub(crate) const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}};
|
pub const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}};
|
||||||
|
@ -5,6 +5,7 @@ edition = "2018"
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
authors = ["jhwgh1968", "Stephen Chung"]
|
authors = ["jhwgh1968", "Stephen Chung"]
|
||||||
description = "Procedural macros support package for Rhai, a scripting language and engine for Rust"
|
description = "Procedural macros support package for Rhai, a scripting language and engine for Rust"
|
||||||
|
keywords = ["rhai", "scripting", "scripting-engine", "scripting-language", "embedded", "plugin", "macros", "code-generation"]
|
||||||
homepage = "https://rhai.rs/book/plugins/index.html"
|
homepage = "https://rhai.rs/book/plugins/index.html"
|
||||||
repository = "https://github.com/rhaiscript/rhai"
|
repository = "https://github.com/rhaiscript/rhai"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
@ -18,6 +18,7 @@ use std::{
|
|||||||
/// Options for calling a script-defined function via [`Engine::call_fn_with_options`].
|
/// Options for calling a script-defined function via [`Engine::call_fn_with_options`].
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[must_use]
|
||||||
pub struct CallFnOptions<'t> {
|
pub struct CallFnOptions<'t> {
|
||||||
/// A value for binding to the `this` pointer (if any).
|
/// A value for binding to the `this` pointer (if any).
|
||||||
pub this_ptr: Option<&'t mut Dynamic>,
|
pub this_ptr: Option<&'t mut Dynamic>,
|
||||||
@ -120,7 +121,7 @@ impl Engine {
|
|||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
args: impl FuncArgs,
|
args: impl FuncArgs,
|
||||||
) -> RhaiResultOf<T> {
|
) -> RhaiResultOf<T> {
|
||||||
self.call_fn_with_options(Default::default(), scope, ast, name, args)
|
self.call_fn_with_options(CallFnOptions::default(), scope, ast, name, args)
|
||||||
}
|
}
|
||||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
||||||
///
|
///
|
||||||
@ -255,20 +256,23 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
crate::func::ensure_no_data_race(name, args, false).map(|_| Dynamic::UNIT)?;
|
crate::func::ensure_no_data_race(name, args, false).map(|_| Dynamic::UNIT)?;
|
||||||
|
|
||||||
if let Some(fn_def) = ast.shared_lib().get_script_fn(name, args.len()) {
|
ast.shared_lib()
|
||||||
self.call_script_fn(
|
.get_script_fn(name, args.len())
|
||||||
global,
|
.map_or_else(
|
||||||
caches,
|
|| Err(ERR::ErrorFunctionNotFound(name.into(), Position::NONE).into()),
|
||||||
scope,
|
|fn_def| {
|
||||||
this_ptr,
|
self.call_script_fn(
|
||||||
fn_def,
|
global,
|
||||||
args,
|
caches,
|
||||||
rewind_scope,
|
scope,
|
||||||
Position::NONE,
|
this_ptr,
|
||||||
|
fn_def,
|
||||||
|
args,
|
||||||
|
rewind_scope,
|
||||||
|
Position::NONE,
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
} else {
|
|
||||||
Err(ERR::ErrorFunctionNotFound(name.into(), Position::NONE).into())
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Module that defines the public compilation API of [`Engine`].
|
//! Module that defines the public compilation API of [`Engine`].
|
||||||
|
|
||||||
use crate::parser::{ParseResult, ParseState};
|
use crate::parser::{ParseResult, ParseState};
|
||||||
use crate::{Engine, OptimizationLevel, Scope, AST};
|
use crate::{Engine, OptimizationLevel, Scope, StringsInterner, AST};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ impl Engine {
|
|||||||
scripts.as_ref(),
|
scripts.as_ref(),
|
||||||
self.token_mapper.as_ref().map(<_>::as_ref),
|
self.token_mapper.as_ref().map(<_>::as_ref),
|
||||||
);
|
);
|
||||||
let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control);
|
let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control);
|
||||||
let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
_ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n"));
|
_ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n"));
|
||||||
@ -294,7 +294,7 @@ impl Engine {
|
|||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
|
|
||||||
let mut peekable = stream.peekable();
|
let mut peekable = stream.peekable();
|
||||||
let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control);
|
let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control);
|
||||||
self.parse_global_expr(&mut peekable, &mut state, |_| {}, self.optimization_level)
|
self.parse_global_expr(&mut peekable, &mut state, |_| {}, self.optimization_level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ pub struct DefinitionsConfig {
|
|||||||
|
|
||||||
impl Default for DefinitionsConfig {
|
impl Default for DefinitionsConfig {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
write_headers: false,
|
write_headers: false,
|
||||||
@ -105,13 +104,13 @@ impl Definitions<'_> {
|
|||||||
/// Headers are always present in content that is expected to be written to a file
|
/// Headers are always present in content that is expected to be written to a file
|
||||||
/// (i.e. `write_to*` and `*_file` methods).
|
/// (i.e. `write_to*` and `*_file` methods).
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn with_headers(mut self, headers: bool) -> Self {
|
pub const fn with_headers(mut self, headers: bool) -> Self {
|
||||||
self.config.write_headers = headers;
|
self.config.write_headers = headers;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Include standard packages when writing definition files.
|
/// Include standard packages when writing definition files.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn include_standard_packages(mut self, include_standard_packages: bool) -> Self {
|
pub const fn include_standard_packages(mut self, include_standard_packages: bool) -> Self {
|
||||||
self.config.include_standard_packages = include_standard_packages;
|
self.config.include_standard_packages = include_standard_packages;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -129,7 +128,6 @@ impl Definitions<'_> {
|
|||||||
}
|
}
|
||||||
/// Get the configuration.
|
/// Get the configuration.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
|
||||||
pub(crate) const fn config(&self) -> &DefinitionsConfig {
|
pub(crate) const fn config(&self) -> &DefinitionsConfig {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
@ -177,19 +175,19 @@ impl Definitions<'_> {
|
|||||||
let mut def_file = String::from("module static;\n\n");
|
let mut def_file = String::from("module static;\n\n");
|
||||||
|
|
||||||
if config.include_standard_packages {
|
if config.include_standard_packages {
|
||||||
def_file += &self.builtin_functions_operators_impl(&config);
|
def_file += &Self::builtin_functions_operators_impl(config);
|
||||||
def_file += "\n";
|
def_file += "\n";
|
||||||
def_file += &self.builtin_functions_impl(&config);
|
def_file += &Self::builtin_functions_impl(config);
|
||||||
def_file += "\n";
|
def_file += "\n";
|
||||||
}
|
}
|
||||||
def_file += &self.static_module_impl(&config);
|
def_file += &self.static_module_impl(config);
|
||||||
def_file += "\n";
|
def_file += "\n";
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
{
|
{
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
for (module_name, module_def) in self.modules_impl(&config) {
|
for (module_name, module_def) in self.modules_impl(config) {
|
||||||
write!(
|
write!(
|
||||||
&mut def_file,
|
&mut def_file,
|
||||||
"\nmodule {module_name} {{\n{module_def}\n}}\n"
|
"\nmodule {module_name} {{\n{module_def}\n}}\n"
|
||||||
@ -199,7 +197,7 @@ impl Definitions<'_> {
|
|||||||
def_file += "\n";
|
def_file += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
def_file += &self.scope_items_impl(&config);
|
def_file += &self.scope_items_impl(config);
|
||||||
|
|
||||||
def_file += "\n";
|
def_file += "\n";
|
||||||
|
|
||||||
@ -220,11 +218,11 @@ impl Definitions<'_> {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
"__builtin__.d.rhai".to_string(),
|
"__builtin__.d.rhai".to_string(),
|
||||||
self.builtin_functions_impl(&config),
|
Self::builtin_functions_impl(config),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"__builtin-operators__.d.rhai".to_string(),
|
"__builtin-operators__.d.rhai".to_string(),
|
||||||
self.builtin_functions_operators_impl(&config),
|
Self::builtin_functions_operators_impl(config),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
@ -233,18 +231,18 @@ impl Definitions<'_> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(std::iter::once((
|
.chain(std::iter::once((
|
||||||
"__static__.d.rhai".to_string(),
|
"__static__.d.rhai".to_string(),
|
||||||
self.static_module_impl(&config),
|
self.static_module_impl(config),
|
||||||
)))
|
)))
|
||||||
.chain(self.scope.iter().map(move |_| {
|
.chain(self.scope.iter().map(move |_| {
|
||||||
(
|
(
|
||||||
"__scope__.d.rhai".to_string(),
|
"__scope__.d.rhai".to_string(),
|
||||||
self.scope_items_impl(&config),
|
self.scope_items_impl(config),
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
.chain(
|
.chain(
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
{
|
{
|
||||||
self.modules_impl(&config)
|
self.modules_impl(config)
|
||||||
.map(|(name, def)| (format!("{name}.d.rhai"), def))
|
.map(|(name, def)| (format!("{name}.d.rhai"), def))
|
||||||
},
|
},
|
||||||
#[cfg(feature = "no_module")]
|
#[cfg(feature = "no_module")]
|
||||||
@ -258,12 +256,12 @@ impl Definitions<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn builtin_functions(&self) -> String {
|
pub fn builtin_functions(&self) -> String {
|
||||||
self.builtin_functions_impl(&self.config)
|
Self::builtin_functions_impl(self.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return definitions for all builtin functions.
|
/// Return definitions for all builtin functions.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn builtin_functions_impl(&self, config: &DefinitionsConfig) -> String {
|
fn builtin_functions_impl(config: DefinitionsConfig) -> String {
|
||||||
let def = include_str!("builtin-functions.d.rhai");
|
let def = include_str!("builtin-functions.d.rhai");
|
||||||
|
|
||||||
if config.write_headers {
|
if config.write_headers {
|
||||||
@ -277,12 +275,12 @@ impl Definitions<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn builtin_functions_operators(&self) -> String {
|
pub fn builtin_functions_operators(&self) -> String {
|
||||||
self.builtin_functions_operators_impl(&self.config)
|
Self::builtin_functions_operators_impl(self.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return definitions for all builtin operators.
|
/// Return definitions for all builtin operators.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn builtin_functions_operators_impl(&self, config: &DefinitionsConfig) -> String {
|
fn builtin_functions_operators_impl(config: DefinitionsConfig) -> String {
|
||||||
let def = include_str!("builtin-operators.d.rhai");
|
let def = include_str!("builtin-operators.d.rhai");
|
||||||
|
|
||||||
if config.write_headers {
|
if config.write_headers {
|
||||||
@ -296,22 +294,22 @@ impl Definitions<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn static_module(&self) -> String {
|
pub fn static_module(&self) -> String {
|
||||||
self.static_module_impl(&self.config)
|
self.static_module_impl(self.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return definitions for all globally available functions and constants.
|
/// Return definitions for all globally available functions and constants.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn static_module_impl(&self, config: &DefinitionsConfig) -> String {
|
fn static_module_impl(&self, config: DefinitionsConfig) -> String {
|
||||||
let mut s = if config.write_headers {
|
let mut s = if config.write_headers {
|
||||||
String::from("module static;\n\n")
|
String::from("module static;\n\n")
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let exclude_flags = if !self.config.include_standard_packages {
|
let exclude_flags = if self.config.include_standard_packages {
|
||||||
ModuleFlags::STANDARD_LIB
|
|
||||||
} else {
|
|
||||||
ModuleFlags::empty()
|
ModuleFlags::empty()
|
||||||
|
} else {
|
||||||
|
ModuleFlags::STANDARD_LIB
|
||||||
};
|
};
|
||||||
|
|
||||||
self.engine
|
self.engine
|
||||||
@ -333,12 +331,12 @@ impl Definitions<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn scope_items(&self) -> String {
|
pub fn scope_items(&self) -> String {
|
||||||
self.scope_items_impl(&self.config)
|
self.scope_items_impl(self.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return definitions for all items inside the [`Scope`], if any.
|
/// Return definitions for all items inside the [`Scope`], if any.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn scope_items_impl(&self, config: &DefinitionsConfig) -> String {
|
fn scope_items_impl(&self, config: DefinitionsConfig) -> String {
|
||||||
let mut s = if config.write_headers {
|
let mut s = if config.write_headers {
|
||||||
String::from("module static;\n\n")
|
String::from("module static;\n\n")
|
||||||
} else {
|
} else {
|
||||||
@ -358,14 +356,14 @@ impl Definitions<'_> {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn modules(&self) -> impl Iterator<Item = (String, String)> + '_ {
|
pub fn modules(&self) -> impl Iterator<Item = (String, String)> + '_ {
|
||||||
self.modules_impl(&self.config)
|
self.modules_impl(self.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a (module name, definitions) pair for each registered static [module][Module].
|
/// Return a (module name, definitions) pair for each registered static [module][Module].
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
fn modules_impl(
|
fn modules_impl(
|
||||||
&self,
|
&self,
|
||||||
config: &DefinitionsConfig,
|
config: DefinitionsConfig,
|
||||||
) -> impl Iterator<Item = (String, String)> + '_ {
|
) -> impl Iterator<Item = (String, String)> + '_ {
|
||||||
let mut m = self
|
let mut m = self
|
||||||
.engine
|
.engine
|
||||||
|
@ -4,7 +4,8 @@ use crate::eval::{Caches, GlobalRuntimeState};
|
|||||||
use crate::parser::ParseState;
|
use crate::parser::ParseState;
|
||||||
use crate::types::dynamic::Variant;
|
use crate::types::dynamic::Variant;
|
||||||
use crate::{
|
use crate::{
|
||||||
reify, Dynamic, Engine, OptimizationLevel, Position, RhaiResult, RhaiResultOf, Scope, AST, ERR,
|
reify, Dynamic, Engine, OptimizationLevel, Position, RhaiResult, RhaiResultOf, Scope,
|
||||||
|
StringsInterner, AST, ERR,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -69,7 +70,7 @@ impl Engine {
|
|||||||
) -> RhaiResultOf<T> {
|
) -> RhaiResultOf<T> {
|
||||||
let ast = self.compile_with_scope_and_optimization_level(
|
let ast = self.compile_with_scope_and_optimization_level(
|
||||||
scope,
|
scope,
|
||||||
&[script],
|
[script],
|
||||||
self.optimization_level,
|
self.optimization_level,
|
||||||
)?;
|
)?;
|
||||||
self.eval_ast_with_scope(scope, &ast)
|
self.eval_ast_with_scope(scope, &ast)
|
||||||
@ -119,7 +120,7 @@ impl Engine {
|
|||||||
let scripts = [script];
|
let scripts = [script];
|
||||||
let (stream, tokenizer_control) =
|
let (stream, tokenizer_control) =
|
||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control);
|
let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control);
|
||||||
|
|
||||||
// No need to optimize a lone expression
|
// No need to optimize a lone expression
|
||||||
let ast = self.parse_global_expr(
|
let ast = self.parse_global_expr(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use crate::parser::{ParseSettingFlags, ParseState};
|
use crate::parser::{ParseSettingFlags, ParseState};
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope};
|
use crate::{Engine, LexError, Map, OptimizationLevel, RhaiResultOf, Scope, StringsInterner};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
@ -117,7 +117,8 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let scope = Scope::new();
|
let scope = Scope::new();
|
||||||
let mut state = ParseState::new(self, &scope, Default::default(), tokenizer_control);
|
let mut state =
|
||||||
|
ParseState::new(self, &scope, StringsInterner::default(), tokenizer_control);
|
||||||
|
|
||||||
let ast = self.parse_global_expr(
|
let ast = self.parse_global_expr(
|
||||||
&mut stream.peekable(),
|
&mut stream.peekable(),
|
||||||
@ -165,7 +166,7 @@ pub fn format_map_as_json(map: &Map) -> String {
|
|||||||
result.push(':');
|
result.push(':');
|
||||||
|
|
||||||
if let Some(val) = value.read_lock::<Map>() {
|
if let Some(val) = value.read_lock::<Map>() {
|
||||||
result.push_str(&format_map_as_json(&*val));
|
result.push_str(&format_map_as_json(&val));
|
||||||
} else if value.is_unit() {
|
} else if value.is_unit() {
|
||||||
result.push_str("null");
|
result.push_str("null");
|
||||||
} else {
|
} else {
|
||||||
|
@ -191,7 +191,7 @@ impl Engine {
|
|||||||
/// Get the default value of the custom state for each evaluation run.
|
/// Get the default value of the custom state for each evaluation run.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn default_tag(&self) -> &Dynamic {
|
pub const fn default_tag(&self) -> &Dynamic {
|
||||||
&self.def_tag
|
&self.def_tag
|
||||||
}
|
}
|
||||||
/// Get a mutable reference to the default value of the custom state for each evaluation run.
|
/// Get a mutable reference to the default value of the custom state for each evaluation run.
|
||||||
|
@ -742,10 +742,10 @@ impl Engine {
|
|||||||
signatures.extend(m.gen_fn_signatures().map(|f| format!("{name}::{f}")));
|
signatures.extend(m.gen_fn_signatures().map(|f| format!("{name}::{f}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
let exclude_flags = if !include_packages {
|
let exclude_flags = if include_packages {
|
||||||
ModuleFlags::INTERNAL | ModuleFlags::STANDARD_LIB
|
|
||||||
} else {
|
|
||||||
ModuleFlags::INTERNAL
|
ModuleFlags::INTERNAL
|
||||||
|
} else {
|
||||||
|
ModuleFlags::INTERNAL | ModuleFlags::STANDARD_LIB
|
||||||
};
|
};
|
||||||
|
|
||||||
signatures.extend(
|
signatures.extend(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::eval::{Caches, GlobalRuntimeState};
|
use crate::eval::{Caches, GlobalRuntimeState};
|
||||||
use crate::parser::ParseState;
|
use crate::parser::ParseState;
|
||||||
use crate::{Engine, RhaiResultOf, Scope, AST};
|
use crate::{Engine, RhaiResultOf, Scope, StringsInterner, AST};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ impl Engine {
|
|||||||
let scripts = [script];
|
let scripts = [script];
|
||||||
let (stream, tokenizer_control) =
|
let (stream, tokenizer_control) =
|
||||||
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
self.lex_raw(&scripts, self.token_mapper.as_ref().map(<_>::as_ref));
|
||||||
let mut state = ParseState::new(self, scope, Default::default(), tokenizer_control);
|
let mut state = ParseState::new(self, scope, StringsInterner::default(), tokenizer_control);
|
||||||
let ast = self.parse(&mut stream.peekable(), &mut state, self.optimization_level)?;
|
let ast = self.parse(&mut stream.peekable(), &mut state, self.optimization_level)?;
|
||||||
self.run_ast_with_scope(scope, &ast)
|
self.run_ast_with_scope(scope, &ast)
|
||||||
}
|
}
|
||||||
|
@ -139,8 +139,8 @@ pub fn format_type(typ: &str, is_return_type: bool) -> std::borrow::Cow<str> {
|
|||||||
} else {
|
} else {
|
||||||
format!("&mut {r}").into()
|
format!("&mut {r}").into()
|
||||||
};
|
};
|
||||||
} else if typ.contains(" ") {
|
} else if typ.contains(' ') {
|
||||||
let typ = typ.replace(" ", "");
|
let typ = typ.replace(' ', "");
|
||||||
let r = format_type(&typ, is_return_type);
|
let r = format_type(&typ, is_return_type);
|
||||||
return r.into_owned().into();
|
return r.into_owned().into();
|
||||||
}
|
}
|
||||||
|
@ -772,7 +772,7 @@ impl AST {
|
|||||||
/// Not available under `no_function`.
|
/// Not available under `no_function`.
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_functions<'a>(&'a self) -> impl Iterator<Item = super::ScriptFnMetadata> + 'a {
|
pub fn iter_functions(&self) -> impl Iterator<Item = super::ScriptFnMetadata> {
|
||||||
self.lib
|
self.lib
|
||||||
.iter_script_fn()
|
.iter_script_fn()
|
||||||
.map(|(.., fn_def)| fn_def.as_ref().into())
|
.map(|(.., fn_def)| fn_def.as_ref().into())
|
||||||
@ -942,7 +942,7 @@ impl Borrow<crate::Module> for AST {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn borrow(&self) -> &crate::Module {
|
fn borrow(&self) -> &crate::Module {
|
||||||
&self.shared_lib()
|
self.shared_lib()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ impl FnCallHashes {
|
|||||||
/// The hash returned is never zero.
|
/// The hash returned is never zero.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn native(&self) -> u64 {
|
pub const fn native(&self) -> u64 {
|
||||||
self.native.get()
|
self.native.get()
|
||||||
}
|
}
|
||||||
/// Get the script hash.
|
/// Get the script hash.
|
||||||
@ -837,18 +837,12 @@ impl Expr {
|
|||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Self::Custom(..) => false,
|
Self::Custom(..) => false,
|
||||||
|
|
||||||
Self::Variable(..) => match token {
|
Self::Variable(..) => matches!(
|
||||||
Token::LeftParen => true,
|
token,
|
||||||
Token::Unit => true,
|
Token::LeftParen | Token::Unit | Token::Bang | Token::DoubleColon
|
||||||
Token::Bang => true,
|
),
|
||||||
Token::DoubleColon => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
|
|
||||||
Self::Property(..) => match token {
|
Self::Property(..) => matches!(token, Token::LeftParen),
|
||||||
Token::LeftParen => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Recursively walk this expression.
|
/// Recursively walk this expression.
|
||||||
|
@ -165,7 +165,7 @@ where
|
|||||||
|
|
||||||
unsafe impl<T: Sync + Send> Sync for SusLock<T> where T: 'static {}
|
unsafe impl<T: Sync + Send> Sync for SusLock<T> where T: 'static {}
|
||||||
unsafe impl<T: Send> Send for SusLock<T> where T: 'static {}
|
unsafe impl<T: Send> Send for SusLock<T> where T: 'static {}
|
||||||
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> where T: 'static {}
|
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> {}
|
||||||
|
|
||||||
impl<T> Drop for SusLock<T>
|
impl<T> Drop for SusLock<T>
|
||||||
where
|
where
|
||||||
@ -174,7 +174,7 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.initialized.load(Ordering::SeqCst) {
|
if self.initialized.load(Ordering::SeqCst) {
|
||||||
unsafe { (&mut *self.data.get()).assume_init_drop() };
|
unsafe { (*self.data.get()).assume_init_drop() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
//! This file is automatically recreated during build time by `build.rs` from `build.template`.
|
//! This file is automatically recreated during build time by `build.rs` from `build.template`.
|
||||||
|
|
||||||
pub(crate) const AHASH_SEED: Option<[u64; 4]> = None;
|
pub const AHASH_SEED: Option<[u64; 4]> = None;
|
||||||
|
@ -72,7 +72,7 @@ impl Caches {
|
|||||||
/// Push an empty function resolution cache onto the stack and make it current.
|
/// Push an empty function resolution cache onto the stack and make it current.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn push_fn_resolution_cache(&mut self) {
|
pub fn push_fn_resolution_cache(&mut self) {
|
||||||
self.0.push(Default::default());
|
self.0.push(FnResolutionCache::default());
|
||||||
}
|
}
|
||||||
/// Rewind the function resolution caches stack to a particular size.
|
/// Rewind the function resolution caches stack to a particular size.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -168,6 +168,7 @@ impl Engine {
|
|||||||
ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into()
|
ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
if end <= start {
|
if end <= start {
|
||||||
(0, 0)
|
(0, 0)
|
||||||
} else if end == crate::INT_BITS && start == 0 {
|
} else if end == crate::INT_BITS && start == 0 {
|
||||||
@ -193,6 +194,7 @@ impl Engine {
|
|||||||
ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into()
|
ERR::ErrorBitFieldBounds(crate::INT_BITS, end, idx_pos).into()
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
if end < start {
|
if end < start {
|
||||||
(0, 0)
|
(0, 0)
|
||||||
} else if end == crate::INT_BITS - 1 && start == 0 {
|
} else if end == crate::INT_BITS - 1 && start == 0 {
|
||||||
@ -237,6 +239,7 @@ impl Engine {
|
|||||||
Ok(Target::Bit {
|
Ok(Target::Bit {
|
||||||
source: target,
|
source: target,
|
||||||
value: bit_value.into(),
|
value: bit_value.into(),
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
bit: bit as u8,
|
bit: bit as u8,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -249,12 +252,14 @@ impl Engine {
|
|||||||
.map_err(|typ| self.make_type_mismatch_err::<crate::INT>(typ, idx_pos))?;
|
.map_err(|typ| self.make_type_mismatch_err::<crate::INT>(typ, idx_pos))?;
|
||||||
|
|
||||||
let (ch, offset) = if index >= 0 {
|
let (ch, offset) = if index >= 0 {
|
||||||
|
#[allow(clippy::absurd_extreme_comparisons)]
|
||||||
if index >= crate::MAX_USIZE_INT {
|
if index >= crate::MAX_USIZE_INT {
|
||||||
return Err(
|
return Err(
|
||||||
ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into()
|
ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_sign_loss)]
|
||||||
let offset = index as usize;
|
let offset = index as usize;
|
||||||
(
|
(
|
||||||
s.chars().nth(offset).ok_or_else(|| {
|
s.chars().nth(offset).ok_or_else(|| {
|
||||||
@ -265,12 +270,13 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
let abs_index = index.unsigned_abs();
|
let abs_index = index.unsigned_abs();
|
||||||
|
|
||||||
if abs_index as u64 > usize::MAX as u64 {
|
if abs_index > usize::MAX as u64 {
|
||||||
return Err(
|
return Err(
|
||||||
ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into()
|
ERR::ErrorStringBounds(s.chars().count(), index, idx_pos).into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
let offset = abs_index as usize;
|
let offset = abs_index as usize;
|
||||||
(
|
(
|
||||||
// Count from end if negative
|
// Count from end if negative
|
||||||
|
@ -59,7 +59,7 @@ impl Dynamic {
|
|||||||
}
|
}
|
||||||
Union::Str(ref s, ..) => (0, 0, s.len()),
|
Union::Str(ref s, ..) => (0, 0, s.len()),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(..) if _top => self.read_lock::<Dynamic>().unwrap().calc_data_sizes(true),
|
Union::Shared(..) if _top => self.read_lock::<Self>().unwrap().calc_data_sizes(true),
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
Union::Shared(..) => {
|
Union::Shared(..) => {
|
||||||
unreachable!("shared values discovered within data: {}", self)
|
unreachable!("shared values discovered within data: {}", self)
|
||||||
|
@ -193,7 +193,7 @@ impl BreakPoint {
|
|||||||
/// Is this [`BreakPoint`] enabled?
|
/// Is this [`BreakPoint`] enabled?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_enabled(&self) -> bool {
|
pub const fn is_enabled(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
Self::AtPosition { enabled, .. } => *enabled,
|
Self::AtPosition { enabled, .. } => *enabled,
|
||||||
@ -268,7 +268,7 @@ impl Debugger {
|
|||||||
/// Create a new [`Debugger`].
|
/// Create a new [`Debugger`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(status: DebuggerStatus, state: Dynamic) -> Self {
|
pub const fn new(status: DebuggerStatus, state: Dynamic) -> Self {
|
||||||
Self {
|
Self {
|
||||||
status,
|
status,
|
||||||
break_points: Vec::new(),
|
break_points: Vec::new(),
|
||||||
@ -297,7 +297,7 @@ impl Debugger {
|
|||||||
pos: Position,
|
pos: Position,
|
||||||
) {
|
) {
|
||||||
self.call_stack.push(CallStackFrame {
|
self.call_stack.push(CallStackFrame {
|
||||||
fn_name: fn_name.into(),
|
fn_name,
|
||||||
args,
|
args,
|
||||||
source,
|
source,
|
||||||
pos,
|
pos,
|
||||||
|
@ -156,7 +156,7 @@ impl Engine {
|
|||||||
.any(|(_, _, f, ..)| f == v.3.as_str()) =>
|
.any(|(_, _, f, ..)| f == v.3.as_str()) =>
|
||||||
{
|
{
|
||||||
let val: Dynamic =
|
let val: Dynamic =
|
||||||
crate::FnPtr::new_unchecked(v.3.as_str(), Default::default()).into();
|
crate::FnPtr::new_unchecked(v.3.as_str(), crate::StaticVec::default()).into();
|
||||||
return Ok(val.into());
|
return Ok(val.into());
|
||||||
}
|
}
|
||||||
Expr::Variable(v, None, ..) => v.0.map_or(0, NonZeroUsize::get),
|
Expr::Variable(v, None, ..) => v.0.map_or(0, NonZeroUsize::get),
|
||||||
@ -186,14 +186,20 @@ impl Engine {
|
|||||||
match scope.search(var_name) {
|
match scope.search(var_name) {
|
||||||
Some(index) => index,
|
Some(index) => index,
|
||||||
None => {
|
None => {
|
||||||
return match self.global_modules.iter().find_map(|m| m.get_var(var_name)) {
|
return self
|
||||||
Some(val) => Ok(val.into()),
|
.global_modules
|
||||||
None => Err(ERR::ErrorVariableNotFound(
|
.iter()
|
||||||
var_name.to_string(),
|
.find_map(|m| m.get_var(var_name))
|
||||||
expr.position(),
|
.map_or_else(
|
||||||
|
|| {
|
||||||
|
Err(ERR::ErrorVariableNotFound(
|
||||||
|
var_name.to_string(),
|
||||||
|
expr.position(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
},
|
||||||
|
|val| Ok(val.into()),
|
||||||
)
|
)
|
||||||
.into()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -533,6 +533,7 @@ impl Engine {
|
|||||||
let index_value = x as INT;
|
let index_value = x as INT;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
#[allow(clippy::absurd_extreme_comparisons)]
|
||||||
if index_value > crate::MAX_USIZE_INT {
|
if index_value > crate::MAX_USIZE_INT {
|
||||||
return Err(ERR::ErrorArithmetic(
|
return Err(ERR::ErrorArithmetic(
|
||||||
format!("for-loop counter overflow: {x}"),
|
format!("for-loop counter overflow: {x}"),
|
||||||
@ -799,10 +800,10 @@ impl Engine {
|
|||||||
Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into())
|
Err(ERR::ErrorModuleNotFound(path.to_string(), path_pos).into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let (export, must_be_indexed) = if !export.is_empty() {
|
let (export, must_be_indexed) = if export.is_empty() {
|
||||||
(export.name.clone(), true)
|
|
||||||
} else {
|
|
||||||
(self.const_empty_string(), false)
|
(self.const_empty_string(), false)
|
||||||
|
} else {
|
||||||
|
(export.name.clone(), true)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !must_be_indexed || module.is_indexed() {
|
if !must_be_indexed || module.is_indexed() {
|
||||||
@ -824,13 +825,14 @@ impl Engine {
|
|||||||
Stmt::Export(x, ..) => {
|
Stmt::Export(x, ..) => {
|
||||||
let (Ident { name, pos, .. }, Ident { name: alias, .. }) = &**x;
|
let (Ident { name, pos, .. }, Ident { name: alias, .. }) = &**x;
|
||||||
// Mark scope variables as public
|
// Mark scope variables as public
|
||||||
if let Some(index) = scope.search(name) {
|
scope.search(name).map_or_else(
|
||||||
let alias = if alias.is_empty() { name } else { alias }.clone();
|
|| Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()),
|
||||||
scope.add_alias_by_index(index, alias.into());
|
|index| {
|
||||||
Ok(Dynamic::UNIT)
|
let alias = if alias.is_empty() { name } else { alias }.clone();
|
||||||
} else {
|
scope.add_alias_by_index(index, alias);
|
||||||
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())
|
Ok(Dynamic::UNIT)
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Share statement
|
// Share statement
|
||||||
@ -838,20 +840,21 @@ impl Engine {
|
|||||||
Stmt::Share(x) => {
|
Stmt::Share(x) => {
|
||||||
x.iter()
|
x.iter()
|
||||||
.try_for_each(|(name, index, pos)| {
|
.try_for_each(|(name, index, pos)| {
|
||||||
if let Some(index) = index
|
index
|
||||||
.map(|n| scope.len() - n.get())
|
.map(|n| scope.len() - n.get())
|
||||||
.or_else(|| scope.search(name))
|
.or_else(|| scope.search(name))
|
||||||
{
|
.map_or_else(
|
||||||
let val = scope.get_mut_by_index(index);
|
|| Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()),
|
||||||
|
|index| {
|
||||||
|
let val = scope.get_mut_by_index(index);
|
||||||
|
|
||||||
if !val.is_shared() {
|
if !val.is_shared() {
|
||||||
// Replace the variable with a shared value.
|
// Replace the variable with a shared value.
|
||||||
*val = std::mem::take(val).into_shared();
|
*val = std::mem::take(val).into_shared();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
},
|
||||||
Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into())
|
)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|_| Dynamic::UNIT)
|
.map(|_| Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,11 @@ use std::{
|
|||||||
/// Values going over bounds are limited to the actual length.
|
/// Values going over bounds are limited to the actual length.
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[allow(
|
||||||
|
clippy::cast_sign_loss,
|
||||||
|
clippy::absurd_extreme_comparisons,
|
||||||
|
clippy::cast_possible_truncation
|
||||||
|
)]
|
||||||
pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (usize, usize) {
|
pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (usize, usize) {
|
||||||
let start = if start < 0 {
|
let start = if start < 0 {
|
||||||
let abs_start = start.unsigned_abs();
|
let abs_start = start.unsigned_abs();
|
||||||
@ -47,6 +52,11 @@ pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (us
|
|||||||
/// Values going over bounds call the provided closure to return a default value or an error.
|
/// Values going over bounds call the provided closure to return a default value or an error.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
#[allow(
|
||||||
|
clippy::cast_sign_loss,
|
||||||
|
clippy::cast_possible_truncation,
|
||||||
|
clippy::absurd_extreme_comparisons
|
||||||
|
)]
|
||||||
pub fn calc_index<E>(
|
pub fn calc_index<E>(
|
||||||
length: usize,
|
length: usize,
|
||||||
start: crate::INT,
|
start: crate::INT,
|
||||||
@ -54,13 +64,14 @@ pub fn calc_index<E>(
|
|||||||
err_func: impl FnOnce() -> Result<usize, E>,
|
err_func: impl FnOnce() -> Result<usize, E>,
|
||||||
) -> Result<usize, E> {
|
) -> Result<usize, E> {
|
||||||
if start < 0 && negative_count_from_end {
|
if start < 0 && negative_count_from_end {
|
||||||
let abs_start = start.unsigned_abs() as usize;
|
let abs_start = start.unsigned_abs();
|
||||||
|
return Ok(if abs_start as u64 > crate::MAX_USIZE_INT as u64 {
|
||||||
// Count from end if negative
|
0
|
||||||
if abs_start <= length {
|
} else {
|
||||||
return Ok(length - abs_start);
|
length - usize::min(abs_start as usize, length)
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if start <= crate::MAX_USIZE_INT && (start as usize) < length {
|
if start <= crate::MAX_USIZE_INT && (start as usize) < length {
|
||||||
return Ok(start as usize);
|
return Ok(start as usize);
|
||||||
}
|
}
|
||||||
@ -313,7 +324,10 @@ impl<'a> Target<'a> {
|
|||||||
|
|
||||||
let value = &mut *source.write_lock::<crate::Blob>().expect("`Blob`");
|
let value = &mut *source.write_lock::<crate::Blob>().expect("`Blob`");
|
||||||
|
|
||||||
value[*index] = (new_byte & 0x00ff) as u8;
|
#[allow(clippy::cast_sign_loss)]
|
||||||
|
{
|
||||||
|
value[*index] = (new_byte & 0x00ff) as u8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
Self::StringChar {
|
Self::StringChar {
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
//! Built-in implementations for common operators.
|
//! Built-in implementations for common operators.
|
||||||
|
|
||||||
|
#![allow(clippy::float_cmp)]
|
||||||
|
|
||||||
use super::call::FnCallArgs;
|
use super::call::FnCallArgs;
|
||||||
use super::native::FnBuiltin;
|
use super::native::FnBuiltin;
|
||||||
|
#[allow(clippy::enum_glob_use)]
|
||||||
use crate::tokenizer::{Token, Token::*};
|
use crate::tokenizer::{Token, Token::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, ExclusiveRange, ImmutableString, InclusiveRange, NativeCallContext, RhaiResult,
|
Dynamic, ExclusiveRange, ImmutableString, InclusiveRange, NativeCallContext, RhaiResult,
|
||||||
@ -68,13 +71,11 @@ fn is_numeric(type_id: TypeId) -> bool {
|
|||||||
|
|
||||||
/// A function that returns `true`.
|
/// A function that returns `true`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
|
||||||
fn const_true_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult {
|
fn const_true_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
Ok(Dynamic::TRUE)
|
Ok(Dynamic::TRUE)
|
||||||
}
|
}
|
||||||
/// A function that returns `false`.
|
/// A function that returns `false`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
|
||||||
fn const_false_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult {
|
fn const_false_fn(_: NativeCallContext, _: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
Ok(Dynamic::FALSE)
|
Ok(Dynamic::FALSE)
|
||||||
}
|
}
|
||||||
@ -143,6 +144,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
|
|||||||
if type1 == type2 {
|
if type1 == type2 {
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -340,6 +342,7 @@ pub fn get_builtin_binary_op_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Option<
|
|||||||
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ty, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::arithmetic::decimal_functions::builtin::*;
|
use crate::packages::arithmetic::decimal_functions::builtin::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -632,6 +635,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
if type1 == type2 {
|
if type1 == type2 {
|
||||||
if type1 == TypeId::of::<INT>() {
|
if type1 == TypeId::of::<INT>() {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
use crate::packages::arithmetic::arith_basic::INT::functions::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -720,6 +724,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type1 == TypeId::of::<crate::Array>() {
|
if type1 == TypeId::of::<crate::Array>() {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::array_basic::array_functions::*;
|
use crate::packages::array_basic::array_functions::*;
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
|
|
||||||
@ -751,6 +756,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type1 == TypeId::of::<crate::Blob>() {
|
if type1 == TypeId::of::<crate::Blob>() {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::blob_basic::blob_functions::*;
|
use crate::packages::blob_basic::blob_functions::*;
|
||||||
use crate::Blob;
|
use crate::Blob;
|
||||||
|
|
||||||
@ -801,6 +807,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
($x:ident, $xx:ident, $y:ty, $yy:ident) => {
|
||||||
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
if (type1, type2) == (TypeId::of::<$x>(), TypeId::of::<$y>()) {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::arithmetic::decimal_functions::builtin::*;
|
use crate::packages::arithmetic::decimal_functions::builtin::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -887,6 +894,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
// array op= any
|
// array op= any
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
if type1 == TypeId::of::<crate::Array>() {
|
if type1 == TypeId::of::<crate::Array>() {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::array_basic::array_functions::*;
|
use crate::packages::array_basic::array_functions::*;
|
||||||
use crate::Array;
|
use crate::Array;
|
||||||
|
|
||||||
@ -916,6 +924,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
|
|
||||||
// blob op= int
|
// blob op= int
|
||||||
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<INT>()) {
|
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<INT>()) {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::blob_basic::blob_functions::*;
|
use crate::packages::blob_basic::blob_functions::*;
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
@ -935,6 +944,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
|
|
||||||
// blob op= char
|
// blob op= char
|
||||||
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<char>()) {
|
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<char>()) {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::blob_basic::blob_functions::*;
|
use crate::packages::blob_basic::blob_functions::*;
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
@ -954,6 +964,7 @@ pub fn get_builtin_op_assignment_fn(op: &Token, x: &Dynamic, y: &Dynamic) -> Opt
|
|||||||
|
|
||||||
// blob op= string
|
// blob op= string
|
||||||
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<ImmutableString>()) {
|
if (type1, type2) == (TypeId::of::<Blob>(), TypeId::of::<ImmutableString>()) {
|
||||||
|
#[allow(clippy::wildcard_imports)]
|
||||||
use crate::packages::blob_basic::blob_functions::*;
|
use crate::packages::blob_basic::blob_functions::*;
|
||||||
|
|
||||||
return match op {
|
return match op {
|
||||||
|
@ -90,11 +90,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
/// exiting the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
/// exiting the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn restore_first_arg(&mut self, args: &mut FnCallArgs<'a>) {
|
pub fn restore_first_arg(&mut self, args: &mut FnCallArgs<'a>) {
|
||||||
if let Some(p) = self.orig_mut.take() {
|
args[0] = self.orig_mut.take().expect("`Some`");
|
||||||
args[0] = p;
|
|
||||||
} else {
|
|
||||||
unreachable!("`Some`");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +112,7 @@ pub fn ensure_no_data_race(fn_name: &str, args: &FnCallArgs, is_ref_mut: bool) -
|
|||||||
if let Some((n, ..)) = args
|
if let Some((n, ..)) = args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.skip(if is_ref_mut { 1 } else { 0 })
|
.skip(usize::from(is_ref_mut))
|
||||||
.find(|(.., a)| a.is_locked())
|
.find(|(.., a)| a.is_locked())
|
||||||
{
|
{
|
||||||
return Err(ERR::ErrorDataRace(
|
return Err(ERR::ErrorDataRace(
|
||||||
@ -277,7 +273,7 @@ impl Engine {
|
|||||||
Some(token) if token.is_op_assignment() => {
|
Some(token) if token.is_op_assignment() => {
|
||||||
let (first_arg, rest_args) = args.split_first().unwrap();
|
let (first_arg, rest_args) = args.split_first().unwrap();
|
||||||
|
|
||||||
get_builtin_op_assignment_fn(token, *first_arg, rest_args[0])
|
get_builtin_op_assignment_fn(token, first_arg, rest_args[0])
|
||||||
.map(|f| FnResolutionCacheEntry {
|
.map(|f| FnResolutionCacheEntry {
|
||||||
func: CallableFunction::Method(Shared::new(f)),
|
func: CallableFunction::Method(Shared::new(f)),
|
||||||
source: None,
|
source: None,
|
||||||
@ -344,7 +340,7 @@ impl Engine {
|
|||||||
name: &str,
|
name: &str,
|
||||||
op_token: Option<&Token>,
|
op_token: Option<&Token>,
|
||||||
hash: u64,
|
hash: u64,
|
||||||
mut args: &mut FnCallArgs,
|
args: &mut FnCallArgs,
|
||||||
is_ref_mut: bool,
|
is_ref_mut: bool,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> RhaiResultOf<(Dynamic, bool)> {
|
) -> RhaiResultOf<(Dynamic, bool)> {
|
||||||
@ -381,7 +377,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let args =
|
let args =
|
||||||
&mut *RestoreOnDrop::lock_if(swap, &mut args, move |a| backup.restore_first_arg(a));
|
&mut *RestoreOnDrop::lock_if(swap, args, move |a| backup.restore_first_arg(a));
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
@ -423,7 +419,7 @@ impl Engine {
|
|||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if trigger {
|
if trigger {
|
||||||
let scope = &mut &mut Scope::new();
|
let scope = &mut Scope::new();
|
||||||
let mut this = Dynamic::NULL;
|
let mut this = Dynamic::NULL;
|
||||||
let node = crate::ast::Stmt::Noop(pos);
|
let node = crate::ast::Stmt::Noop(pos);
|
||||||
let node = (&node).into();
|
let node = (&node).into();
|
||||||
@ -597,12 +593,13 @@ impl Engine {
|
|||||||
let num_params = _args[1].as_int().expect("`INT`");
|
let num_params = _args[1].as_int().expect("`INT`");
|
||||||
|
|
||||||
return Ok((
|
return Ok((
|
||||||
if num_params < 0 || num_params > crate::MAX_USIZE_INT {
|
if (0..=crate::MAX_USIZE_INT).contains(&num_params) {
|
||||||
false
|
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||||
} else {
|
|
||||||
let hash_script =
|
let hash_script =
|
||||||
calc_fn_hash(None, fn_name.as_str(), num_params as usize);
|
calc_fn_hash(None, fn_name.as_str(), num_params as usize);
|
||||||
self.has_script_fn(global, caches, hash_script)
|
self.has_script_fn(global, caches, hash_script)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
false,
|
false,
|
||||||
@ -647,12 +644,11 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut empty_scope;
|
let mut empty_scope;
|
||||||
let scope = match _scope {
|
let scope = if let Some(scope) = _scope {
|
||||||
Some(scope) => scope,
|
scope
|
||||||
None => {
|
} else {
|
||||||
empty_scope = Scope::new();
|
empty_scope = Scope::new();
|
||||||
&mut empty_scope
|
&mut empty_scope
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let orig_source = mem::replace(&mut global.source, source.clone());
|
let orig_source = mem::replace(&mut global.source, source.clone());
|
||||||
@ -676,7 +672,7 @@ impl Engine {
|
|||||||
backup.change_first_arg_to_copy(_args);
|
backup.change_first_arg_to_copy(_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = &mut *RestoreOnDrop::lock_if(swap, &mut _args, move |a| {
|
let args = &mut *RestoreOnDrop::lock_if(swap, _args, move |a| {
|
||||||
backup.restore_first_arg(a)
|
backup.restore_first_arg(a)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -901,7 +897,7 @@ impl Engine {
|
|||||||
call_args = &mut _arg_values;
|
call_args = &mut _arg_values;
|
||||||
}
|
}
|
||||||
// Recalculate the hash based on the new function name and new arguments
|
// Recalculate the hash based on the new function name and new arguments
|
||||||
hash = if !is_anon && !is_valid_function_name(&fn_name) {
|
hash = if !is_anon && !is_valid_function_name(fn_name) {
|
||||||
FnCallHashes::from_native(calc_fn_hash(
|
FnCallHashes::from_native(calc_fn_hash(
|
||||||
None,
|
None,
|
||||||
fn_name,
|
fn_name,
|
||||||
@ -963,7 +959,7 @@ impl Engine {
|
|||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
let mut first_arg = first_arg;
|
let mut first_arg = first_arg;
|
||||||
let mut a_expr = args_expr;
|
let mut a_expr = args_expr;
|
||||||
let mut total_args = if first_arg.is_some() { 1 } else { 0 } + a_expr.len();
|
let mut total_args = usize::from(first_arg.is_some()) + a_expr.len();
|
||||||
let mut curry = FnArgsVec::new_const();
|
let mut curry = FnArgsVec::new_const();
|
||||||
let mut name = fn_name;
|
let mut name = fn_name;
|
||||||
let mut hashes = hashes;
|
let mut hashes = hashes;
|
||||||
@ -1077,9 +1073,10 @@ impl Engine {
|
|||||||
.as_int()
|
.as_int()
|
||||||
.map_err(|typ| self.make_type_mismatch_err::<crate::INT>(typ, arg_pos))?;
|
.map_err(|typ| self.make_type_mismatch_err::<crate::INT>(typ, arg_pos))?;
|
||||||
|
|
||||||
return Ok(if num_params < 0 || num_params > crate::MAX_USIZE_INT {
|
return Ok(if !(0..=crate::MAX_USIZE_INT).contains(&num_params) {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
|
#[allow(clippy::cast_sign_loss)]
|
||||||
let hash_script = calc_fn_hash(None, &fn_name, num_params as usize);
|
let hash_script = calc_fn_hash(None, &fn_name, num_params as usize);
|
||||||
self.has_script_fn(global, caches, hash_script)
|
self.has_script_fn(global, caches, hash_script)
|
||||||
}
|
}
|
||||||
@ -1437,7 +1434,7 @@ impl Engine {
|
|||||||
// No optimizations because we only run it once
|
// No optimizations because we only run it once
|
||||||
let ast = self.compile_with_scope_and_optimization_level(
|
let ast = self.compile_with_scope_and_optimization_level(
|
||||||
&Scope::new(),
|
&Scope::new(),
|
||||||
&[script],
|
[script],
|
||||||
#[cfg(not(feature = "no_optimize"))]
|
#[cfg(not(feature = "no_optimize"))]
|
||||||
OptimizationLevel::None,
|
OptimizationLevel::None,
|
||||||
#[cfg(feature = "no_optimize")]
|
#[cfg(feature = "no_optimize")]
|
||||||
|
@ -132,9 +132,7 @@ impl CallableFunction {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
match self {
|
match self {
|
||||||
Self::Pure(..) | Self::Method(..) => true,
|
Self::Pure(..) | Self::Method(..) | Self::Plugin(..) | Self::Iterator(..) => true,
|
||||||
Self::Plugin(..) => true,
|
|
||||||
Self::Iterator(..) => true,
|
|
||||||
Self::Script(..) => false,
|
Self::Script(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,8 +145,9 @@ impl CallableFunction {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
match self {
|
match self {
|
||||||
Self::Plugin(..) => FnAccess::Public,
|
Self::Plugin(..) | Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => {
|
||||||
Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => FnAccess::Public,
|
FnAccess::Public
|
||||||
|
}
|
||||||
Self::Script(f) => f.access,
|
Self::Script(f) => f.access,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ pub trait Func<ARGS, RET> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
|
||||||
fn create_from_script(self, script: &str, entry_point: &str) -> ParseResult<Self::Output>;
|
fn create_from_script(self, script: &str, entry_point: &str) -> ParseResult<Self::Output>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ impl<'a> NativeCallContext<'a> {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new_with_all_fields(
|
pub const fn new_with_all_fields(
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
fn_name: &'a str,
|
fn_name: &'a str,
|
||||||
source: Option<&'a str>,
|
source: Option<&'a str>,
|
||||||
@ -240,7 +240,7 @@ impl<'a> NativeCallContext<'a> {
|
|||||||
/// Custom state kept in a [`Dynamic`].
|
/// Custom state kept in a [`Dynamic`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn tag(&self) -> Option<&Dynamic> {
|
pub const fn tag(&self) -> Option<&Dynamic> {
|
||||||
Some(&self.global.tag)
|
Some(&self.global.tag)
|
||||||
}
|
}
|
||||||
/// Get an iterator over the current set of modules imported via `import` statements
|
/// Get an iterator over the current set of modules imported via `import` statements
|
||||||
@ -278,7 +278,7 @@ impl<'a> NativeCallContext<'a> {
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn iter_namespaces(&self) -> impl Iterator<Item = &crate::Module> {
|
pub fn iter_namespaces(&self) -> impl Iterator<Item = &crate::Module> {
|
||||||
self.global.lib.iter().map(|m| m.as_ref())
|
self.global.lib.iter().map(AsRef::as_ref)
|
||||||
}
|
}
|
||||||
/// _(internals)_ The current stack of namespaces containing definitions of all script-defined functions.
|
/// _(internals)_ The current stack of namespaces containing definitions of all script-defined functions.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
|
@ -65,6 +65,7 @@
|
|||||||
#![warn(clippy::undocumented_unsafe_blocks)]
|
#![warn(clippy::undocumented_unsafe_blocks)]
|
||||||
#![allow(clippy::unit_arg)]
|
#![allow(clippy::unit_arg)]
|
||||||
#![allow(clippy::missing_errors_doc)]
|
#![allow(clippy::missing_errors_doc)]
|
||||||
|
#![allow(clippy::missing_panics_doc)]
|
||||||
#![allow(clippy::used_underscore_binding)]
|
#![allow(clippy::used_underscore_binding)]
|
||||||
#![allow(clippy::inline_always)]
|
#![allow(clippy::inline_always)]
|
||||||
#![allow(clippy::module_name_repetitions)]
|
#![allow(clippy::module_name_repetitions)]
|
||||||
|
@ -6,12 +6,12 @@ use std::prelude::v1::*;
|
|||||||
|
|
||||||
/// Run custom restoration logic upon the end of scope.
|
/// Run custom restoration logic upon the end of scope.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct RestoreOnDrop<'a, T, R: FnOnce(&mut T)> {
|
pub struct RestoreOnDrop<'a, T: ?Sized, R: FnOnce(&mut T)> {
|
||||||
value: &'a mut T,
|
value: &'a mut T,
|
||||||
restore: Option<R>,
|
restore: Option<R>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> {
|
impl<'a, T: ?Sized, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> {
|
||||||
/// Create a new [`RestoreOnDrop`] that locks a mutable reference and runs restoration logic at
|
/// Create a new [`RestoreOnDrop`] that locks a mutable reference and runs restoration logic at
|
||||||
/// the end of scope only when `need_restore` is `true`.
|
/// the end of scope only when `need_restore` is `true`.
|
||||||
///
|
///
|
||||||
@ -39,7 +39,7 @@ impl<'a, T, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> {
|
impl<'a, T: ?Sized, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(restore) = self.restore.take() {
|
if let Some(restore) = self.restore.take() {
|
||||||
@ -48,7 +48,7 @@ impl<'a, T, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> {
|
impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -57,7 +57,7 @@ impl<'a, T, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, R: FnOnce(&mut T)> DerefMut for RestoreOnDrop<'a, T, R> {
|
impl<'a, T: ?Sized, R: FnOnce(&mut T)> DerefMut for RestoreOnDrop<'a, T, R> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.value
|
self.value
|
||||||
|
Loading…
Reference in New Issue
Block a user