Merge pull request #399 from schungx/master

Use no-std-compat to build no-std.
This commit is contained in:
Stephen Chung 2021-04-17 15:35:20 +08:00 committed by GitHub
commit b5ade8dad0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 415 additions and 380 deletions

View File

@ -4,6 +4,12 @@ Rhai Release Notes
Version 0.20.1 Version 0.20.1
============== ==============
Breaking changes
----------------
* `Dynamic::is_shared` and `Dynamic::is_locked` are removed under the `no_closure` feature. They used to always return `false`.
* `Engine::call_fn` now evaluates the `AST` before calling the function.
Version 0.20.0 Version 0.20.0
============== ==============

View File

@ -41,7 +41,7 @@ internals = [] # expose internal data structures
unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers. unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers.
metadata = ["serde_json", "rhai_codegen/metadata"] # enable exporting functions metadata metadata = ["serde_json", "rhai_codegen/metadata"] # enable exporting functions metadata
no_std = ["num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"] no_std = ["no-std-compat", "num-traits/libm", "core-error", "libm", "ahash/compile-time-rng"]
# compiling for WASM # compiling for WASM
wasm-bindgen = ["instant/wasm-bindgen"] wasm-bindgen = ["instant/wasm-bindgen"]
@ -53,6 +53,12 @@ codegen-units = 1
#opt-level = "z" # optimize for size #opt-level = "z" # optimize for size
#panic = 'abort' # remove stack backtrace for no-std #panic = 'abort' # remove stack backtrace for no-std
[dependencies.no-std-compat]
version = "0.4"
default_features = false
features = ["alloc"]
optional = true
[dependencies.libm] [dependencies.libm]
version = "0.2" version = "0.2"
default_features = false default_features = false

View File

@ -3,26 +3,28 @@
use crate::dynamic::{AccessMode, Union}; use crate::dynamic::{AccessMode, Union};
use crate::fn_native::shared_make_mut; use crate::fn_native::shared_make_mut;
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::stdlib::{
boxed::Box,
collections::BTreeMap,
fmt,
hash::Hash,
iter::empty,
num::{NonZeroU8, NonZeroUsize},
ops::{Add, AddAssign, Deref, DerefMut},
vec,
vec::Vec,
};
use crate::token::Token; use crate::token::Token;
use crate::utils::calc_fn_hash; use crate::utils::calc_fn_hash;
use crate::{ use crate::{
Dynamic, FnNamespace, FnPtr, Identifier, ImmutableString, Module, Position, Shared, StaticVec, Dynamic, FnNamespace, FnPtr, Identifier, ImmutableString, Module, Position, Shared, StaticVec,
INT, INT,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
collections::BTreeMap,
fmt,
hash::Hash,
iter::empty,
num::{NonZeroU8, NonZeroUsize},
ops::{Add, AddAssign, Deref, DerefMut},
};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::{stdlib::str::FromStr, FLOAT}; use std::str::FromStr;
#[cfg(not(feature = "no_float"))]
use crate::FLOAT;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use num_traits::Float; use num_traits::Float;
@ -62,11 +64,11 @@ pub struct ScriptFnDef {
pub params: StaticVec<Identifier>, pub params: StaticVec<Identifier>,
/// Access to external variables. /// Access to external variables.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
pub externals: crate::stdlib::collections::BTreeSet<Identifier>, pub externals: std::collections::BTreeSet<Identifier>,
/// Function doc-comments (if any). /// Function doc-comments (if any).
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
pub comments: StaticVec<crate::stdlib::string::String>, pub comments: StaticVec<std::string::String>,
} }
impl fmt::Display for ScriptFnDef { impl fmt::Display for ScriptFnDef {
@ -90,6 +92,7 @@ impl fmt::Display for ScriptFnDef {
} }
/// A type containing the metadata of a script-defined function. /// A type containing the metadata of a script-defined function.
///
/// Not available under `no_function`. /// Not available under `no_function`.
/// ///
/// Created by [`AST::iter_functions`]. /// Created by [`AST::iter_functions`].
@ -265,6 +268,7 @@ impl AST {
} }
/// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions. /// _(INTERNALS)_ Get the internal shared [`Module`] containing all script-defined functions.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
///
/// Not available under `no_function`. /// Not available under `no_function`.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated = "this method is volatile and may change"] #[deprecated = "this method is volatile and may change"]
@ -282,6 +286,7 @@ impl AST {
} }
/// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions. /// _(INTERNALS)_ Get the internal [`Module`] containing all script-defined functions.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
///
/// Not available under `no_function`. /// Not available under `no_function`.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated = "this method is volatile and may change"] #[deprecated = "this method is volatile and may change"]
@ -318,6 +323,7 @@ impl AST {
} }
/// Clone the [`AST`]'s functions into a new [`AST`]. /// Clone the [`AST`]'s functions into a new [`AST`].
/// No statements are cloned. /// No statements are cloned.
///
/// Not available under `no_function`. /// Not available under `no_function`.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
@ -328,6 +334,7 @@ impl AST {
} }
/// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate. /// Clone the [`AST`]'s functions into a new [`AST`] based on a filter predicate.
/// No statements are cloned. /// No statements are cloned.
///
/// Not available under `no_function`. /// Not available under `no_function`.
/// ///
/// This operation is cheap because functions are shared. /// This operation is cheap because functions are shared.
@ -650,7 +657,7 @@ impl AST {
} }
/// Iterate through all function definitions. /// Iterate through all function definitions.
/// ///
/// Not available under [`no_function`]. /// Not available under `no_function`.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
@ -1473,7 +1480,7 @@ pub struct FloatWrapper<F>(F);
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
impl Hash for FloatWrapper<FLOAT> { impl Hash for FloatWrapper<FLOAT> {
#[inline(always)] #[inline(always)]
fn hash<H: crate::stdlib::hash::Hasher>(&self, state: &mut H) { fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0.to_ne_bytes().hash(state); self.0.to_ne_bytes().hash(state);
} }
} }
@ -1495,7 +1502,7 @@ impl<F: Float> AsMut<F> for FloatWrapper<F> {
} }
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
impl<F: Float> crate::stdlib::ops::Deref for FloatWrapper<F> { impl<F: Float> std::ops::Deref for FloatWrapper<F> {
type Target = F; type Target = F;
#[inline(always)] #[inline(always)]
@ -1505,7 +1512,7 @@ impl<F: Float> crate::stdlib::ops::Deref for FloatWrapper<F> {
} }
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
impl<F: Float> crate::stdlib::ops::DerefMut for FloatWrapper<F> { impl<F: Float> std::ops::DerefMut for FloatWrapper<F> {
#[inline(always)] #[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0 &mut self.0
@ -2032,8 +2039,8 @@ mod tests {
/// This test is to make sure no code changes increase the sizes of critical data structures. /// This test is to make sure no code changes increase the sizes of critical data structures.
#[test] #[test]
fn check_struct_sizes() { fn check_struct_sizes() {
use crate::stdlib::mem::size_of;
use crate::*; use crate::*;
use std::mem::size_of;
assert_eq!(size_of::<Dynamic>(), 16); assert_eq!(size_of::<Dynamic>(), 16);
assert_eq!(size_of::<Option<Dynamic>>(), 16); assert_eq!(size_of::<Option<Dynamic>>(), 16);

View File

@ -205,12 +205,17 @@ fn main() {
.iter_raw() .iter_raw()
.enumerate() .enumerate()
.for_each(|(i, (name, constant, value))| { .for_each(|(i, (name, constant, value))| {
#[cfg(not(feature = "no_closure"))]
let value_is_shared = if value.is_shared() { " (shared" } else { "" };
#[cfg(feature = "no_closure")]
let value_is_shared = "";
println!( println!(
"[{}] {}{}{} = {:?}", "[{}] {}{}{} = {:?}",
i + 1, i + 1,
if constant { "const " } else { "" }, if constant { "const " } else { "" },
name, name,
if value.is_shared() { " (shared)" } else { "" }, value_is_shared,
*value.read_lock::<Dynamic>().unwrap(), *value.read_lock::<Dynamic>().unwrap(),
) )
}); });

View File

@ -2,15 +2,15 @@
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast}; use crate::r#unsafe::{unsafe_cast_box, unsafe_try_cast};
use crate::stdlib::{ use crate::{FnPtr, ImmutableString, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{type_name, Any, TypeId}, any::{type_name, Any, TypeId},
boxed::Box,
fmt, fmt,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
string::String,
}; };
use crate::{FnPtr, ImmutableString, INT};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::{ast::FloatWrapper, FLOAT}; use crate::{ast::FloatWrapper, FLOAT};
@ -26,7 +26,7 @@ use crate::Map;
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
use crate::stdlib::time::Instant; use std::time::Instant;
use fmt::Debug; use fmt::Debug;
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
@ -35,7 +35,7 @@ use instant::Instant;
mod private { mod private {
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::stdlib::any::Any; use std::any::Any;
/// A sealed trait that prevents other crates from implementing [`Variant`]. /// A sealed trait that prevents other crates from implementing [`Variant`].
pub trait Sealed {} pub trait Sealed {}
@ -199,11 +199,11 @@ enum DynamicReadLockInner<'d, T: Variant + Clone> {
/// A read guard to a shared [`RefCell`][std::cell::RefCell]. /// A read guard to a shared [`RefCell`][std::cell::RefCell].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
Guard(crate::stdlib::cell::Ref<'d, Dynamic>), Guard(std::cell::Ref<'d, Dynamic>),
/// A read guard to a shared [`RwLock`][std::sync::RwLock]. /// A read guard to a shared [`RwLock`][std::sync::RwLock].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Guard(crate::stdlib::sync::RwLockReadGuard<'d, Dynamic>), Guard(std::sync::RwLockReadGuard<'d, Dynamic>),
} }
impl<'d, T: Variant + Clone> Deref for DynamicReadLock<'d, T> { impl<'d, T: Variant + Clone> Deref for DynamicReadLock<'d, T> {
@ -236,11 +236,11 @@ enum DynamicWriteLockInner<'d, T: Variant + Clone> {
/// A write guard to a shared [`RefCell`][std::cell::RefCell]. /// A write guard to a shared [`RefCell`][std::cell::RefCell].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
Guard(crate::stdlib::cell::RefMut<'d, Dynamic>), Guard(std::cell::RefMut<'d, Dynamic>),
/// A write guard to a shared [`RwLock`][std::sync::RwLock]. /// A write guard to a shared [`RwLock`][std::sync::RwLock].
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
Guard(crate::stdlib::sync::RwLockWriteGuard<'d, Dynamic>), Guard(std::sync::RwLockWriteGuard<'d, Dynamic>),
} }
impl<'d, T: Variant + Clone> Deref for DynamicWriteLock<'d, T> { impl<'d, T: Variant + Clone> Deref for DynamicWriteLock<'d, T> {
@ -281,7 +281,8 @@ impl Dynamic {
} }
/// Is the value held by this [`Dynamic`] shared? /// Is the value held by this [`Dynamic`] shared?
/// ///
/// Always [`false`] under the `no_closure` feature. /// Not available under `no_closure`.
#[cfg(not(feature = "no_closure"))]
#[inline(always)] #[inline(always)]
pub fn is_shared(&self) -> bool { pub fn is_shared(&self) -> bool {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -948,10 +949,6 @@ impl Dynamic {
/// values. /// values.
/// ///
/// If the [`Dynamic`] value is already shared, this method returns itself. /// If the [`Dynamic`] value is already shared, this method returns itself.
///
/// # Panics
///
/// Panics under the `no_closure` feature.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[inline(always)] #[inline(always)]
pub fn into_shared(self) -> Self { pub fn into_shared(self) -> Self {
@ -1122,12 +1119,15 @@ impl Dynamic {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn cast<T: Variant + Clone>(self) -> T { pub fn cast<T: Variant + Clone>(self) -> T {
#[cfg(not(feature = "no_closure"))]
let self_type_name = if self.is_shared() { let self_type_name = if self.is_shared() {
// Avoid panics/deadlocks with shared values // Avoid panics/deadlocks with shared values
"<shared>" "<shared>"
} else { } else {
self.type_name() self.type_name()
}; };
#[cfg(feature = "no_closure")]
let self_type_name = self.type_name();
self.try_cast::<T>().unwrap_or_else(|| { self.try_cast::<T>().unwrap_or_else(|| {
panic!( panic!(
@ -1233,7 +1233,7 @@ impl Dynamic {
pub(crate) fn flatten_in_place(&mut self) { pub(crate) fn flatten_in_place(&mut self) {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
match self.0 { match self.0 {
Union::Shared(_, _) => match crate::stdlib::mem::take(self).0 { Union::Shared(_, _) => match std::mem::take(self).0 {
Union::Shared(cell, _) => { Union::Shared(cell, _) => {
*self = crate::fn_native::shared_try_take(cell).map_or_else( *self = crate::fn_native::shared_try_take(cell).map_or_else(
|cell| { |cell| {
@ -1259,11 +1259,14 @@ impl Dynamic {
} }
/// Is the [`Dynamic`] a shared value that is locked? /// Is the [`Dynamic`] a shared value that is locked?
/// ///
/// Not available under `no_closure`.
///
/// ## Note /// ## Note
/// ///
/// Under the `sync` feature, shared values use [`RwLock`][std::sync::RwLock] and they are never locked. /// Under the `sync` feature, shared values use [`RwLock`][std::sync::RwLock] and they are never locked.
/// Access just waits until the [`RwLock`][std::sync::RwLock] is released. /// Access just waits until the [`RwLock`][std::sync::RwLock] is released.
/// So this method always returns [`false`] under [`Sync`]. /// So this method always returns [`false`] under [`Sync`].
#[cfg(not(feature = "no_closure"))]
#[inline(always)] #[inline(always)]
pub fn is_locked(&self) -> bool { pub fn is_locked(&self) -> bool {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -1714,13 +1717,13 @@ impl From<&ImmutableString> for Dynamic {
impl From<&crate::Identifier> for Dynamic { impl From<&crate::Identifier> for Dynamic {
#[inline(always)] #[inline(always)]
fn from(value: &crate::Identifier) -> Self { fn from(value: &crate::Identifier) -> Self {
crate::stdlib::string::ToString::to_string(value).into() std::string::ToString::to_string(value).into()
} }
} }
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
impl<T: Variant + Clone> From<crate::stdlib::vec::Vec<T>> for Dynamic { impl<T: Variant + Clone> From<std::vec::Vec<T>> for Dynamic {
#[inline(always)] #[inline(always)]
fn from(value: crate::stdlib::vec::Vec<T>) -> Self { fn from(value: std::vec::Vec<T>) -> Self {
Self(Union::Array( Self(Union::Array(
Box::new(value.into_iter().map(Dynamic::from).collect()), Box::new(value.into_iter().map(Dynamic::from).collect()),
AccessMode::ReadWrite, AccessMode::ReadWrite,
@ -1738,7 +1741,7 @@ impl<T: Variant + Clone> From<&[T]> for Dynamic {
} }
} }
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
impl<T: Variant + Clone> crate::stdlib::iter::FromIterator<T> for Dynamic { impl<T: Variant + Clone> std::iter::FromIterator<T> for Dynamic {
#[inline(always)] #[inline(always)]
fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self { fn from_iter<X: IntoIterator<Item = T>>(iter: X) -> Self {
Self(Union::Array( Self(Union::Array(
@ -1749,11 +1752,11 @@ impl<T: Variant + Clone> crate::stdlib::iter::FromIterator<T> for Dynamic {
} }
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
impl<K: Into<crate::Identifier>, T: Variant + Clone> From<crate::stdlib::collections::HashMap<K, T>> impl<K: Into<crate::Identifier>, T: Variant + Clone> From<std::collections::HashMap<K, T>>
for Dynamic for Dynamic
{ {
#[inline(always)] #[inline(always)]
fn from(value: crate::stdlib::collections::HashMap<K, T>) -> Self { fn from(value: std::collections::HashMap<K, T>) -> Self {
Self(Union::Map( Self(Union::Map(
Box::new( Box::new(
value value
@ -1766,11 +1769,11 @@ impl<K: Into<crate::Identifier>, T: Variant + Clone> From<crate::stdlib::collect
} }
} }
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
impl<K: Into<crate::Identifier>, T: Variant + Clone> impl<K: Into<crate::Identifier>, T: Variant + Clone> From<std::collections::BTreeMap<K, T>>
From<crate::stdlib::collections::BTreeMap<K, T>> for Dynamic for Dynamic
{ {
#[inline(always)] #[inline(always)]
fn from(value: crate::stdlib::collections::BTreeMap<K, T>) -> Self { fn from(value: std::collections::BTreeMap<K, T>) -> Self {
Self(Union::Map( Self(Union::Map(
Box::new( Box::new(
value value

View File

@ -10,27 +10,26 @@ use crate::module::NamespaceRef;
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::packages::{Package, StandardPackage}; use crate::packages::{Package, StandardPackage};
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
use crate::stdlib::{
any::{type_name, TypeId},
borrow::Cow,
boxed::Box,
collections::{BTreeMap, BTreeSet},
fmt, format,
hash::{Hash, Hasher},
num::{NonZeroU8, NonZeroUsize},
ops::DerefMut,
string::{String, ToString},
vec::Vec,
};
use crate::syntax::CustomSyntax; use crate::syntax::CustomSyntax;
use crate::utils::get_hasher; use crate::utils::get_hasher;
use crate::{ use crate::{
Dynamic, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, Position, RhaiResult, Dynamic, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, Position, RhaiResult,
Scope, Shared, StaticVec, Scope, Shared, StaticVec,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{type_name, TypeId},
borrow::Cow,
collections::{BTreeMap, BTreeSet},
fmt,
hash::{Hash, Hasher},
num::{NonZeroU8, NonZeroUsize},
ops::{Deref, DerefMut},
};
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::{calc_fn_hash, stdlib::iter::empty, Array}; use crate::{calc_fn_hash, Array};
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::Map; use crate::Map;
@ -344,7 +343,7 @@ impl<'a> Target<'a> {
} }
} }
/// Is the `Target` a shared value? /// Is the `Target` a shared value?
#[allow(dead_code)] #[cfg(not(feature = "no_closure"))]
#[inline(always)] #[inline(always)]
pub fn is_shared(&self) -> bool { pub fn is_shared(&self) -> bool {
match self { match self {
@ -467,9 +466,11 @@ impl<'a> From<&'a mut Dynamic> for Target<'a> {
} }
} }
impl AsRef<Dynamic> for Target<'_> { impl Deref for Target<'_> {
type Target = Dynamic;
#[inline(always)] #[inline(always)]
fn as_ref(&self) -> &Dynamic { fn deref(&self) -> &Dynamic {
match self { match self {
Self::Ref(r) => *r, Self::Ref(r) => *r,
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -482,9 +483,16 @@ impl AsRef<Dynamic> for Target<'_> {
} }
} }
impl AsMut<Dynamic> for Target<'_> { impl AsRef<Dynamic> for Target<'_> {
#[inline(always)] #[inline(always)]
fn as_mut(&mut self) -> &mut Dynamic { fn as_ref(&self) -> &Dynamic {
self
}
}
impl DerefMut for Target<'_> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Dynamic {
match self { match self {
Self::Ref(r) => *r, Self::Ref(r) => *r,
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
@ -497,6 +505,13 @@ impl AsMut<Dynamic> for Target<'_> {
} }
} }
impl AsMut<Dynamic> for Target<'_> {
#[inline(always)]
fn as_mut(&mut self) -> &mut Dynamic {
self
}
}
impl<T: Into<Dynamic>> From<T> for Target<'_> { impl<T: Into<Dynamic>> From<T> for Target<'_> {
#[inline(always)] #[inline(always)]
fn from(value: T) -> Self { fn from(value: T) -> Self {
@ -600,7 +615,7 @@ pub struct Limits {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub max_function_expr_depth: Option<NonZeroUsize>, pub max_function_expr_depth: Option<NonZeroUsize>,
/// Maximum number of operations allowed to run. /// Maximum number of operations allowed to run.
pub max_operations: Option<crate::stdlib::num::NonZeroU64>, pub max_operations: Option<std::num::NonZeroU64>,
/// Maximum number of [modules][Module] allowed to load. /// Maximum number of [modules][Module] allowed to load.
/// ///
/// Set to zero to effectively disable loading any [module][Module]. /// Set to zero to effectively disable loading any [module][Module].
@ -1105,8 +1120,6 @@ impl Engine {
// Pop the last index value // Pop the last index value
let idx_val = idx_values.pop().unwrap(); let idx_val = idx_values.pop().unwrap();
let target_val = target.as_mut();
match chain_type { match chain_type {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
ChainType::Index => { ChainType::Index => {
@ -1118,8 +1131,7 @@ impl Engine {
let idx_pos = x.lhs.position(); let idx_pos = x.lhs.position();
let idx_val = idx_val.as_index_value(); let idx_val = idx_val.as_index_value();
let obj_ptr = &mut self.get_indexed_mut( let obj_ptr = &mut self.get_indexed_mut(
mods, state, lib, target_val, idx_val, idx_pos, false, is_ref, true, mods, state, lib, target, idx_val, idx_pos, false, is_ref, true, level,
level,
)?; )?;
self.eval_dot_index_chain_helper( self.eval_dot_index_chain_helper(
@ -1137,7 +1149,7 @@ impl Engine {
// `call_setter` is introduced to bypass double mutable borrowing of target // `call_setter` is introduced to bypass double mutable borrowing of target
let _call_setter = match self.get_indexed_mut( let _call_setter = match self.get_indexed_mut(
mods, state, lib, target_val, idx_val, pos, true, is_ref, false, level, mods, state, lib, target, idx_val, pos, true, is_ref, false, level,
) { ) {
// Indexed value is a reference - update directly // Indexed value is a reference - update directly
Ok(obj_ptr) => { Ok(obj_ptr) => {
@ -1158,12 +1170,15 @@ impl Engine {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
if let Some(mut new_val) = _call_setter { if let Some(mut new_val) = _call_setter {
let val_type_name = target_val.type_name(); let val_type_name = target.type_name();
let ((_, val_pos), _) = new_val; let ((_, val_pos), _) = new_val;
let hash_set = let hash_set = FnCallHash::from_native(calc_fn_hash(
FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_SET, 3)); std::iter::empty(),
let args = &mut [target_val, &mut idx_val2, &mut (new_val.0).0]; FN_IDX_SET,
3,
));
let args = &mut [target, &mut idx_val2, &mut (new_val.0).0];
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true, mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
@ -1188,7 +1203,7 @@ impl Engine {
_ => { _ => {
let idx_val = idx_val.as_index_value(); let idx_val = idx_val.as_index_value();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target_val, idx_val, pos, false, is_ref, true, level, mods, state, lib, target, idx_val, pos, false, is_ref, true, level,
) )
.map(|v| (v.take_or_clone(), false)) .map(|v| (v.take_or_clone(), false))
} }
@ -1215,11 +1230,11 @@ impl Engine {
unreachable!("function call in dot chain should not be namespace-qualified") unreachable!("function call in dot chain should not be namespace-qualified")
} }
// {xxx:map}.id op= ??? // {xxx:map}.id op= ???
Expr::Property(x) if target_val.is::<Map>() && new_val.is_some() => { Expr::Property(x) if target.is::<Map>() && new_val.is_some() => {
let Ident { name, pos, .. } = &x.2; let Ident { name, pos, .. } = &x.2;
let index = name.into(); let index = name.into();
let val = self.get_indexed_mut( let val = self.get_indexed_mut(
mods, state, lib, target_val, index, *pos, true, is_ref, false, level, mods, state, lib, target, index, *pos, true, is_ref, false, level,
)?; )?;
let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap(); let ((new_val, new_pos), (op_info, op_pos)) = new_val.unwrap();
self.eval_op_assignment( self.eval_op_assignment(
@ -1228,11 +1243,11 @@ impl Engine {
Ok((Dynamic::UNIT, true)) Ok((Dynamic::UNIT, true))
} }
// {xxx:map}.id // {xxx:map}.id
Expr::Property(x) if target_val.is::<Map>() => { Expr::Property(x) if target.is::<Map>() => {
let Ident { name, pos, .. } = &x.2; let Ident { name, pos, .. } = &x.2;
let index = name.into(); let index = name.into();
let val = self.get_indexed_mut( let val = self.get_indexed_mut(
mods, state, lib, target_val, index, *pos, false, is_ref, false, level, mods, state, lib, target, index, *pos, false, is_ref, false, level,
)?; )?;
Ok((val.take_or_clone(), false)) Ok((val.take_or_clone(), false))
@ -1269,7 +1284,7 @@ impl Engine {
Expr::Property(x) => { Expr::Property(x) => {
let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref(); let ((getter, hash_get), _, Ident { pos, .. }) = x.as_ref();
let hash = FnCallHash::from_native(*hash_get); let hash = FnCallHash::from_native(*hash_get);
let mut args = [target_val]; let mut args = [target.as_mut()];
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None, mods, state, lib, getter, hash, &mut args, is_ref, true, *pos, None,
level, level,
@ -1277,13 +1292,13 @@ impl Engine {
.map(|(v, _)| (v, false)) .map(|(v, _)| (v, false))
} }
// {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr // {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr
Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target_val.is::<Map>() => { Expr::Index(x, x_pos) | Expr::Dot(x, x_pos) if target.is::<Map>() => {
let mut val = match &x.lhs { let mut val = match &x.lhs {
Expr::Property(p) => { Expr::Property(p) => {
let Ident { name, pos, .. } = &p.2; let Ident { name, pos, .. } = &p.2;
let index = name.into(); let index = name.into();
self.get_indexed_mut( self.get_indexed_mut(
mods, state, lib, target_val, index, *pos, false, is_ref, true, mods, state, lib, target, index, *pos, false, is_ref, true,
level, level,
)? )?
} }
@ -1319,7 +1334,7 @@ impl Engine {
p.as_ref(); p.as_ref();
let hash_get = FnCallHash::from_native(*hash_get); let hash_get = FnCallHash::from_native(*hash_get);
let hash_set = FnCallHash::from_native(*hash_set); let hash_set = FnCallHash::from_native(*hash_set);
let arg_values = &mut [target_val, &mut Default::default()]; let arg_values = &mut [target.as_mut(), &mut Default::default()];
let args = &mut arg_values[..1]; let args = &mut arg_values[..1];
let (mut val, updated) = self.exec_fn_call( let (mut val, updated) = self.exec_fn_call(
mods, state, lib, getter, hash_get, args, is_ref, true, *pos, mods, state, lib, getter, hash_get, args, is_ref, true, *pos,
@ -1432,7 +1447,7 @@ impl Engine {
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?; self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
// Constants cannot be modified // Constants cannot be modified
if target.as_ref().is_read_only() && new_val.is_some() { if target.is_read_only() && new_val.is_some() {
return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into(); return EvalAltResult::ErrorAssignmentToConstant(x.2.to_string(), pos).into();
} }
@ -1675,7 +1690,8 @@ impl Engine {
_ if _indexers => { _ if _indexers => {
let type_name = target.type_name(); let type_name = target.type_name();
let args = &mut [target, &mut _idx]; let args = &mut [target, &mut _idx];
let hash_get = FnCallHash::from_native(calc_fn_hash(empty(), FN_IDX_GET, 2)); let hash_get =
FnCallHash::from_native(calc_fn_hash(std::iter::empty(), FN_IDX_GET, 2));
self.exec_fn_call( self.exec_fn_call(
_mods, state, _lib, FN_IDX_GET, hash_get, args, _is_ref, true, idx_pos, None, _mods, state, _lib, FN_IDX_GET, hash_get, args, _is_ref, true, idx_pos, None,
_level, _level,
@ -1977,7 +1993,7 @@ impl Engine {
mut new_value: Dynamic, mut new_value: Dynamic,
new_value_pos: Position, new_value_pos: Position,
) -> Result<(), Box<EvalAltResult>> { ) -> Result<(), Box<EvalAltResult>> {
if target.as_ref().is_read_only() { if target.is_read_only() {
unreachable!("LHS should not be read-only"); unreachable!("LHS should not be read-only");
} }
@ -1990,11 +2006,16 @@ impl Engine {
let mut lock_guard; let mut lock_guard;
let lhs_ptr_inner; let lhs_ptr_inner;
if cfg!(not(feature = "no_closure")) && target.is_shared() { #[cfg(not(feature = "no_closure"))]
lock_guard = target.as_mut().write_lock::<Dynamic>().unwrap(); let target_is_shared = target.is_shared();
lhs_ptr_inner = lock_guard.deref_mut(); #[cfg(feature = "no_closure")]
let target_is_shared = false;
if target_is_shared {
lock_guard = target.write_lock::<Dynamic>().unwrap();
lhs_ptr_inner = &mut *lock_guard;
} else { } else {
lhs_ptr_inner = target.as_mut(); lhs_ptr_inner = &mut *target;
} }
let hash = hash_op_assign; let hash = hash_op_assign;
@ -2070,7 +2091,7 @@ impl Engine {
self.inc_operations(state, pos)?; self.inc_operations(state, pos)?;
if lhs_ptr.as_ref().is_read_only() { if lhs_ptr.is_read_only() {
// Assignment to constant variable // Assignment to constant variable
EvalAltResult::ErrorAssignmentToConstant( EvalAltResult::ErrorAssignmentToConstant(
lhs_expr.get_variable_name(false).unwrap().to_string(), lhs_expr.get_variable_name(false).unwrap().to_string(),
@ -2314,7 +2335,12 @@ impl Engine {
let loop_var = scope.get_mut_by_index(index); let loop_var = scope.get_mut_by_index(index);
let value = iter_value.flatten(); let value = iter_value.flatten();
if cfg!(not(feature = "no_closure")) && loop_var.is_shared() { #[cfg(not(feature = "no_closure"))]
let loop_var_is_shared = loop_var.is_shared();
#[cfg(feature = "no_closure")]
let loop_var_is_shared = false;
if loop_var_is_shared {
*loop_var.write_lock().unwrap() = value; *loop_var.write_lock().unwrap() = value;
} else { } else {
*loop_var = value; *loop_var = value;
@ -2571,7 +2597,7 @@ impl Engine {
if !val.is_shared() { if !val.is_shared() {
// Replace the variable with a shared value. // Replace the variable with a shared value.
*val = crate::stdlib::mem::take(val).into_shared(); *val = std::mem::take(val).into_shared();
} }
} }
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)

View File

@ -6,15 +6,13 @@ use crate::fn_native::{FnCallArgs, SendSync};
use crate::fn_register::RegisterNativeFunction; use crate::fn_register::RegisterNativeFunction;
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::parser::ParseState; use crate::parser::ParseState;
use crate::stdlib::{
any::{type_name, TypeId},
boxed::Box,
string::String,
};
use crate::{ use crate::{
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module, scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module,
NativeCallContext, ParseError, Position, RhaiResult, Shared, AST, NativeCallContext, ParseError, Position, RhaiResult, Shared, AST,
}; };
use std::any::{type_name, TypeId};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -61,7 +59,7 @@ impl Engine {
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
let mut param_type_names: crate::StaticVec<_> = F::param_names() let mut param_type_names: crate::StaticVec<_> = F::param_names()
.iter() .iter()
.map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty))) .map(|ty| std::format!("_: {}", self.map_type_name(ty)))
.collect(); .collect();
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
@ -121,8 +119,8 @@ impl Engine {
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
let param_type_names: crate::StaticVec<_> = F::param_names() let param_type_names: crate::StaticVec<_> = F::param_names()
.iter() .iter()
.map(|ty| crate::stdlib::format!("_: {}", self.map_type_name(ty))) .map(|ty| std::format!("_: {}", self.map_type_name(ty)))
.chain(crate::stdlib::iter::once( .chain(std::iter::once(
self.map_type_name(F::return_type_name()).into(), self.map_type_name(F::return_type_name()).into(),
)) ))
.collect(); .collect();
@ -905,7 +903,7 @@ impl Engine {
module: Shared<Module>, module: Shared<Module>,
) -> &mut Self { ) -> &mut Self {
fn register_static_module_raw( fn register_static_module_raw(
root: &mut crate::stdlib::collections::BTreeMap<Identifier, Shared<Module>>, root: &mut std::collections::BTreeMap<Identifier, Shared<Module>>,
name: impl AsRef<str> + Into<Identifier>, name: impl AsRef<str> + Into<Identifier>,
module: Shared<Module>, module: Shared<Module>,
) { ) {
@ -1039,8 +1037,8 @@ impl Engine {
ast::{ASTNode, Expr, Stmt}, ast::{ASTNode, Expr, Stmt},
fn_native::shared_take_or_clone, fn_native::shared_take_or_clone,
module::resolvers::StaticModuleResolver, module::resolvers::StaticModuleResolver,
stdlib::collections::BTreeSet,
}; };
use std::collections::BTreeSet;
fn collect_imports( fn collect_imports(
ast: &AST, ast: &AST,
@ -1169,12 +1167,12 @@ impl Engine {
/// Read the contents of a file into a string. /// Read the contents of a file into a string.
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
fn read_file(path: crate::stdlib::path::PathBuf) -> Result<String, Box<EvalAltResult>> { fn read_file(path: std::path::PathBuf) -> Result<String, Box<EvalAltResult>> {
use crate::stdlib::io::Read; use std::io::Read;
let mut f = crate::stdlib::fs::File::open(path.clone()).map_err(|err| { let mut f = std::fs::File::open(path.clone()).map_err(|err| {
EvalAltResult::ErrorSystem( EvalAltResult::ErrorSystem(
crate::stdlib::format!("Cannot open script file '{}'", path.to_string_lossy()), std::format!("Cannot open script file '{}'", path.to_string_lossy()),
err.into(), err.into(),
) )
})?; })?;
@ -1183,7 +1181,7 @@ impl Engine {
f.read_to_string(&mut contents).map_err(|err| { f.read_to_string(&mut contents).map_err(|err| {
EvalAltResult::ErrorSystem( EvalAltResult::ErrorSystem(
crate::stdlib::format!("Cannot read script file '{}'", path.to_string_lossy()), std::format!("Cannot read script file '{}'", path.to_string_lossy()),
err.into(), err.into(),
) )
})?; })?;
@ -1224,10 +1222,7 @@ impl Engine {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
#[inline(always)] #[inline(always)]
pub fn compile_file( pub fn compile_file(&self, path: std::path::PathBuf) -> Result<AST, Box<EvalAltResult>> {
&self,
path: crate::stdlib::path::PathBuf,
) -> Result<AST, Box<EvalAltResult>> {
self.compile_file_with_scope(&Default::default(), path) self.compile_file_with_scope(&Default::default(), path)
} }
/// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation. /// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation.
@ -1269,7 +1264,7 @@ impl Engine {
pub fn compile_file_with_scope( pub fn compile_file_with_scope(
&self, &self,
scope: &Scope, scope: &Scope,
path: crate::stdlib::path::PathBuf, path: std::path::PathBuf,
) -> Result<AST, Box<EvalAltResult>> { ) -> Result<AST, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?)) Self::read_file(path).and_then(|contents| Ok(self.compile_with_scope(scope, &contents)?))
} }
@ -1465,7 +1460,7 @@ impl Engine {
#[inline(always)] #[inline(always)]
pub fn eval_file<T: Variant + Clone>( pub fn eval_file<T: Variant + Clone>(
&self, &self,
path: crate::stdlib::path::PathBuf, path: std::path::PathBuf,
) -> Result<T, Box<EvalAltResult>> { ) -> Result<T, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.eval::<T>(&contents)) Self::read_file(path).and_then(|contents| self.eval::<T>(&contents))
} }
@ -1496,7 +1491,7 @@ impl Engine {
pub fn eval_file_with_scope<T: Variant + Clone>( pub fn eval_file_with_scope<T: Variant + Clone>(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
path: crate::stdlib::path::PathBuf, path: std::path::PathBuf,
) -> Result<T, Box<EvalAltResult>> { ) -> Result<T, Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.eval_with_scope::<T>(scope, &contents)) Self::read_file(path).and_then(|contents| self.eval_with_scope::<T>(scope, &contents))
} }
@ -1711,10 +1706,7 @@ impl Engine {
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
#[inline(always)] #[inline(always)]
pub fn consume_file( pub fn consume_file(&self, path: std::path::PathBuf) -> Result<(), Box<EvalAltResult>> {
&self,
path: crate::stdlib::path::PathBuf,
) -> Result<(), Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.consume(&contents)) Self::read_file(path).and_then(|contents| self.consume(&contents))
} }
/// Evaluate a file with own scope, but throw away the result and only return error (if any). /// Evaluate a file with own scope, but throw away the result and only return error (if any).
@ -1727,7 +1719,7 @@ impl Engine {
pub fn consume_file_with_scope( pub fn consume_file_with_scope(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
path: crate::stdlib::path::PathBuf, path: std::path::PathBuf,
) -> Result<(), Box<EvalAltResult>> { ) -> Result<(), Box<EvalAltResult>> {
Self::read_file(path).and_then(|contents| self.consume_with_scope(scope, &contents)) Self::read_file(path).and_then(|contents| self.consume_with_scope(scope, &contents))
} }
@ -1787,12 +1779,10 @@ impl Engine {
/// Call a script function defined in an [`AST`] with multiple arguments. /// Call a script function defined in an [`AST`] with multiple arguments.
/// Arguments are passed as a tuple. /// Arguments are passed as a tuple.
/// ///
/// ## Warning /// The [`AST`] is evaluated before calling the function.
/// /// This allows a script to load the necessary modules.
/// The [`AST`] is _not_ evaluated before calling the function. The function is called as-is. /// This is usually desired. If not, a specialized [`AST`] can be prepared that contains only
/// /// function definitions without any body script via [`AST::clear_statements`].
/// If the [`AST`] needs to be evaluated before calling the function (usually to load external modules),
/// use [`call_fn_dynamic`][Engine::call_fn_dynamic].
/// ///
/// # Example /// # Example
/// ///
@ -1838,9 +1828,9 @@ impl Engine {
) -> Result<T, Box<EvalAltResult>> { ) -> Result<T, Box<EvalAltResult>> {
let mut arg_values: crate::StaticVec<_> = Default::default(); let mut arg_values: crate::StaticVec<_> = Default::default();
args.parse(&mut arg_values); args.parse(&mut arg_values);
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect(); let mut args: crate::StaticVec<_> = arg_values.iter_mut().collect();
let result = self.call_fn_dynamic_raw(scope, ast, false, name, &mut None, args.as_mut())?; let result = self.call_fn_dynamic_raw(scope, ast, true, name, &mut None, &mut args)?;
let typ = self.map_type_name(result.type_name()); let typ = self.map_type_name(result.type_name());
@ -1856,8 +1846,7 @@ impl Engine {
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments /// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
/// and optionally a value for binding to the `this` pointer. /// and optionally a value for binding to the `this` pointer.
/// ///
/// There is also an option to evaluate the [`AST`] (e.g. to configuration the environment) /// There is an option to evaluate the [`AST`] to load necessary modules before calling the function.
/// before calling the function.
/// ///
/// # WARNING /// # WARNING
/// ///
@ -1887,19 +1876,19 @@ impl Engine {
/// scope.push("foo", 42_i64); /// scope.push("foo", 42_i64);
/// ///
/// // Call the script-defined function /// // Call the script-defined function
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add", None, [ "abc".into(), 123_i64.into() ])?; /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add", None, [ "abc".into(), 123_i64.into() ])?;
/// // ^^^^ no 'this' pointer /// // ^^^^ no 'this' pointer
/// assert_eq!(result.cast::<i64>(), 168); /// assert_eq!(result.cast::<i64>(), 168);
/// ///
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add1", None, [ "abc".into() ])?; /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "add1", None, [ "abc".into() ])?;
/// assert_eq!(result.cast::<i64>(), 46); /// assert_eq!(result.cast::<i64>(), 46);
/// ///
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "bar", None, [])?; /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "bar", None, [])?;
/// assert_eq!(result.cast::<i64>(), 21); /// assert_eq!(result.cast::<i64>(), 21);
/// ///
/// let mut value: Dynamic = 1_i64.into(); /// let mut value: Dynamic = 1_i64.into();
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "action", Some(&mut value), [ 41_i64.into() ])?; /// let result = engine.call_fn_dynamic(&mut scope, &ast, true, "action", Some(&mut value), [ 41_i64.into() ])?;
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer /// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
/// assert_eq!(value.as_int().unwrap(), 42); /// assert_eq!(value.as_int().unwrap(), 42);
/// # } /// # }
/// # Ok(()) /// # Ok(())
@ -1918,7 +1907,7 @@ impl Engine {
) -> RhaiResult { ) -> RhaiResult {
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect(); let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, args.as_mut()) self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, &mut 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.
/// ///
@ -2002,7 +1991,7 @@ impl Engine {
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
let lib = Default::default(); let lib = Default::default();
let stmt = crate::stdlib::mem::take(ast.statements_mut()); let stmt = std::mem::take(ast.statements_mut());
crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level) crate::optimize::optimize_into_ast(self, scope, stmt.into_vec(), lib, optimization_level)
} }
/// Generate a list of all registered functions. /// Generate a list of all registered functions.
@ -2013,15 +2002,15 @@ impl Engine {
/// 2) Functions in registered sub-modules /// 2) Functions in registered sub-modules
/// 3) Functions in packages (optional) /// 3) Functions in packages (optional)
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
pub fn gen_fn_signatures(&self, include_packages: bool) -> crate::stdlib::vec::Vec<String> { pub fn gen_fn_signatures(&self, include_packages: bool) -> std::vec::Vec<String> {
let mut signatures: crate::stdlib::vec::Vec<_> = Default::default(); let mut signatures: std::vec::Vec<_> = Default::default();
signatures.extend(self.global_namespace.gen_fn_signatures()); signatures.extend(self.global_namespace.gen_fn_signatures());
self.global_sub_modules.iter().for_each(|(name, m)| { self.global_sub_modules.iter().for_each(|(name, m)| {
signatures.extend( signatures.extend(
m.gen_fn_signatures() m.gen_fn_signatures()
.map(|f| crate::stdlib::format!("{}::{}", name, f)), .map(|f| std::format!("{}::{}", name, f)),
) )
}); });

View File

@ -1,15 +1,13 @@
//! Configuration settings for [`Engine`]. //! Configuration settings for [`Engine`].
use crate::stdlib::{format, string::String};
use crate::token::Token; use crate::token::Token;
use crate::Engine; use crate::Engine;
use crate::{engine::Precedence, Identifier}; use crate::{engine::Precedence, Identifier};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
use crate::stdlib::num::{NonZeroU64, NonZeroUsize}; use std::num::{NonZeroU64, NonZeroUsize};
#[cfg(not(feature = "no_module"))]
use crate::stdlib::boxed::Box;
impl Engine { impl Engine {
/// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation. /// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.

View File

@ -4,8 +4,8 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::stdlib::vec::Vec;
use crate::{Dynamic, StaticVec}; use crate::{Dynamic, StaticVec};
use std::vec::Vec;
/// Trait that parses arguments to a function call. /// Trait that parses arguments to a function call.
/// ///

View File

@ -2,8 +2,10 @@
use crate::engine::OP_CONTAINS; use crate::engine::OP_CONTAINS;
use crate::fn_native::{FnCallArgs, NativeCallContext}; use crate::fn_native::{FnCallArgs, NativeCallContext};
use crate::stdlib::{any::TypeId, format, string::ToString};
use crate::{Dynamic, ImmutableString, RhaiResult, INT}; use crate::{Dynamic, ImmutableString, RhaiResult, INT};
use std::any::TypeId;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;

View File

@ -10,16 +10,6 @@ use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn};
use crate::fn_native::{FnAny, FnCallArgs}; use crate::fn_native::{FnAny, FnCallArgs};
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::stdlib::{
any::{type_name, TypeId},
boxed::Box,
convert::TryFrom,
format,
iter::{empty, once},
mem,
string::{String, ToString},
vec::Vec,
};
use crate::{ use crate::{
ast::{Expr, Stmt}, ast::{Expr, Stmt},
fn_native::CallableFunction, fn_native::CallableFunction,
@ -29,6 +19,14 @@ use crate::{
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, EvalAltResult, FnPtr, calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, EvalAltResult, FnPtr,
ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec, ImmutableString, Module, ParseErrorType, Position, Scope, StaticVec,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{type_name, TypeId},
convert::TryFrom,
iter::{empty, once},
mem,
};
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::Map; use crate::Map;
@ -465,7 +463,7 @@ impl Engine {
) -> RhaiResult { ) -> RhaiResult {
#[inline(always)] #[inline(always)]
fn make_error( fn make_error(
name: crate::stdlib::string::String, name: std::string::String,
fn_def: &crate::ast::ScriptFnDef, fn_def: &crate::ast::ScriptFnDef,
state: &State, state: &State,
err: Box<EvalAltResult>, err: Box<EvalAltResult>,
@ -512,7 +510,7 @@ impl Engine {
.iter() .iter()
.zip(args.iter_mut().map(|v| mem::take(*v))) .zip(args.iter_mut().map(|v| mem::take(*v)))
.map(|(name, value)| { .map(|(name, value)| {
let var_name: crate::stdlib::borrow::Cow<'_, str> = let var_name: std::borrow::Cow<'_, str> =
crate::r#unsafe::unsafe_cast_var_name_to_lifetime(name).into(); crate::r#unsafe::unsafe_cast_var_name_to_lifetime(name).into();
(var_name, value) (var_name, value)
}), }),
@ -913,15 +911,14 @@ impl Engine {
let new_hash = FnCallHash::from_script(calc_fn_hash(empty(), fn_name, args_len)); let new_hash = FnCallHash::from_script(calc_fn_hash(empty(), fn_name, args_len));
// Arguments are passed as-is, adding the curried arguments // Arguments are passed as-is, adding the curried arguments
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>(); let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
let mut arg_values = curry let mut args = curry
.iter_mut() .iter_mut()
.chain(call_args.iter_mut()) .chain(call_args.iter_mut())
.collect::<StaticVec<_>>(); .collect::<StaticVec<_>>();
let args = arg_values.as_mut();
// Map it to name(args) in function-call style // Map it to name(args) in function-call style
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, fn_name, new_hash, args, false, false, pos, None, level, mods, state, lib, fn_name, new_hash, &mut args, false, false, pos, None, level,
) )
} }
KEYWORD_FN_PTR_CALL => { KEYWORD_FN_PTR_CALL => {
@ -952,15 +949,14 @@ impl Engine {
); );
// Replace the first argument with the object pointer, adding the curried arguments // Replace the first argument with the object pointer, adding the curried arguments
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>(); let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
let mut arg_values = once(obj) let mut args = once(obj)
.chain(curry.iter_mut()) .chain(curry.iter_mut())
.chain(call_args.iter_mut()) .chain(call_args.iter_mut())
.collect::<StaticVec<_>>(); .collect::<StaticVec<_>>();
let args = arg_values.as_mut();
// Map it to name(args) in function-call style // Map it to name(args) in function-call style
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, fn_name, new_hash, args, is_ref, true, pos, None, level, mods, state, lib, fn_name, new_hash, &mut args, is_ref, true, pos, None, level,
) )
} }
KEYWORD_FN_PTR_CURRY => { KEYWORD_FN_PTR_CURRY => {
@ -1030,13 +1026,12 @@ impl Engine {
}; };
// Attached object pointer in front of the arguments // Attached object pointer in front of the arguments
let mut arg_values = once(obj) let mut args = once(obj)
.chain(call_args.iter_mut()) .chain(call_args.iter_mut())
.collect::<StaticVec<_>>(); .collect::<StaticVec<_>>();
let args = arg_values.as_mut();
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, fn_name, hash, args, is_ref, true, pos, None, level, mods, state, lib, fn_name, hash, &mut args, is_ref, true, pos, None, level,
) )
} }
}?; }?;
@ -1314,7 +1309,12 @@ impl Engine {
self.inc_operations(state, pos)?; self.inc_operations(state, pos)?;
args = if target.is_shared() || target.is_value() { #[cfg(not(feature = "no_closure"))]
let target_is_shared = target.is_shared();
#[cfg(feature = "no_closure")]
let target_is_shared = false;
args = if target_is_shared || target.is_value() {
arg_values.insert(0, target.take_or_clone().flatten()); arg_values.insert(0, target.take_or_clone().flatten());
arg_values.iter_mut().collect() arg_values.iter_mut().collect()
} else { } else {
@ -1339,10 +1339,8 @@ impl Engine {
} }
} }
let args = args.as_mut();
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, name, hash, args, is_ref, false, pos, capture, level, mods, state, lib, name, hash, &mut args, is_ref, false, pos, capture, level,
) )
.map(|(v, _)| v) .map(|(v, _)| v)
} }
@ -1398,7 +1396,12 @@ impl Engine {
self.inc_operations(state, pos)?; self.inc_operations(state, pos)?;
if target.is_shared() || target.is_value() { #[cfg(not(feature = "no_closure"))]
let target_is_shared = target.is_shared();
#[cfg(feature = "no_closure")]
let target_is_shared = false;
if target_is_shared || target.is_value() {
arg_values[0] = target.take_or_clone().flatten(); arg_values[0] = target.take_or_clone().flatten();
args = arg_values.iter_mut().collect(); args = arg_values.iter_mut().collect();
} else { } else {
@ -1458,7 +1461,6 @@ impl Engine {
if fn_def.body.is_empty() { if fn_def.body.is_empty() {
Ok(Dynamic::UNIT) Ok(Dynamic::UNIT)
} else { } else {
let args = args.as_mut();
let new_scope = &mut Default::default(); let new_scope = &mut Default::default();
let mut source = module.id_raw().cloned(); let mut source = module.id_raw().cloned();
@ -1467,7 +1469,7 @@ impl Engine {
let level = level + 1; let level = level + 1;
let result = self.call_script_fn( let result = self.call_script_fn(
new_scope, mods, state, lib, &mut None, fn_def, args, pos, level, new_scope, mods, state, lib, &mut None, fn_def, &mut args, pos, level,
); );
state.source = source; state.source = source;
@ -1479,17 +1481,13 @@ impl Engine {
Some(f) if f.is_plugin_fn() => f Some(f) if f.is_plugin_fn() => f
.get_plugin_fn() .get_plugin_fn()
.clone() .clone()
.call( .call((self, fn_name, module.id(), &*mods, lib).into(), &mut args)
(self, fn_name, module.id(), &*mods, lib).into(),
args.as_mut(),
)
.map_err(|err| err.fill_position(pos)), .map_err(|err| err.fill_position(pos)),
Some(f) if f.is_native() => f.get_native_fn()( Some(f) if f.is_native() => {
(self, fn_name, module.id(), &*mods, lib).into(), f.get_native_fn()((self, fn_name, module.id(), &*mods, lib).into(), &mut args)
args.as_mut(), .map_err(|err| err.fill_position(pos))
) }
.map_err(|err| err.fill_position(pos)),
Some(f) => unreachable!("unknown function type: {:?}", f), Some(f) => unreachable!("unknown function type: {:?}", f),

View File

@ -4,8 +4,9 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::stdlib::{boxed::Box, string::ToString};
use crate::{Engine, EvalAltResult, ParseError, Scope, AST}; use crate::{Engine, EvalAltResult, ParseError, Scope, AST};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// Trait to create a Rust closure from a script. /// Trait to create a Rust closure from a script.
/// ///

View File

@ -3,19 +3,19 @@
use crate::ast::{FnAccess, FnCallHash}; use crate::ast::{FnAccess, FnCallHash};
use crate::engine::Imports; use crate::engine::Imports;
use crate::plugin::PluginFunction; use crate::plugin::PluginFunction;
use crate::stdlib::{
boxed::Box,
convert::{TryFrom, TryInto},
fmt,
iter::{empty, once},
mem,
string::String,
};
use crate::token::is_valid_identifier; use crate::token::is_valid_identifier;
use crate::{ use crate::{
calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Identifier, ImmutableString, Module, calc_fn_hash, Dynamic, Engine, EvalAltResult, EvalContext, Identifier, ImmutableString, Module,
Position, RhaiResult, StaticVec, Position, RhaiResult, StaticVec,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
convert::{TryFrom, TryInto},
fmt,
iter::{empty, once},
mem,
};
/// Trait that maps to `Send + Sync` only under the `sync` feature. /// Trait that maps to `Send + Sync` only under the `sync` feature.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
@ -33,19 +33,19 @@ impl<T> SendSync for T {}
/// Immutable reference-counted container. /// Immutable reference-counted container.
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub use crate::stdlib::rc::Rc as Shared; pub use std::rc::Rc as Shared;
/// Immutable reference-counted container. /// Immutable reference-counted container.
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub use crate::stdlib::sync::Arc as Shared; pub use std::sync::Arc as Shared;
/// Synchronized shared object. /// Synchronized shared object.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub use crate::stdlib::cell::RefCell as Locked; pub use std::cell::RefCell as Locked;
/// Synchronized shared object. /// Synchronized shared object.
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub use crate::stdlib::sync::RwLock as Locked; pub use std::sync::RwLock as Locked;
/// Context of a native Rust function call. /// Context of a native Rust function call.
#[derive(Debug)] #[derive(Debug)]
@ -348,7 +348,7 @@ impl FnPtr {
arg_values.iter_mut().collect() arg_values.iter_mut().collect()
}; };
ctx.call_fn_dynamic_raw(self.fn_name(), is_method, args.as_mut()) ctx.call_fn_dynamic_raw(self.fn_name(), is_method, &mut args)
} }
} }

View File

@ -5,8 +5,10 @@
use crate::dynamic::{DynamicWriteLock, Variant}; use crate::dynamic::{DynamicWriteLock, Variant};
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync}; use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
use crate::r#unsafe::unsafe_try_cast; use crate::r#unsafe::unsafe_try_cast;
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String, vec};
use crate::{Dynamic, EvalAltResult, NativeCallContext}; use crate::{Dynamic, EvalAltResult, NativeCallContext};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::TypeId, mem};
// These types are used to build a unique _marker_ tuple type for each combination // These types are used to build a unique _marker_ tuple type for each combination
// of function parameter types in order to make each trait implementation unique. // of function parameter types in order to make each trait implementation unique.
@ -91,9 +93,9 @@ macro_rules! def_register {
RET: Variant + Clone RET: Variant + Clone
> RegisterNativeFunction<($($mark,)*), ()> for FN { > RegisterNativeFunction<($($mark,)*), ()> for FN {
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<RET>() }
#[inline(always)] fn into_callable_function(self) -> CallableFunction { #[inline(always)] fn into_callable_function(self) -> CallableFunction {
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| { CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types! // The arguments are assumed to be of the correct number and types!
@ -115,9 +117,9 @@ macro_rules! def_register {
RET: Variant + Clone RET: Variant + Clone
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN { > RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<RET>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<RET>() }
#[inline(always)] fn into_callable_function(self) -> CallableFunction { #[inline(always)] fn into_callable_function(self) -> CallableFunction {
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types! // The arguments are assumed to be of the correct number and types!
@ -139,9 +141,9 @@ macro_rules! def_register {
RET: Variant + Clone RET: Variant + Clone
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN { > RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
#[inline(always)] fn into_callable_function(self) -> CallableFunction { #[inline(always)] fn into_callable_function(self) -> CallableFunction {
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| { CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types! // The arguments are assumed to be of the correct number and types!
@ -160,9 +162,9 @@ macro_rules! def_register {
RET: Variant + Clone RET: Variant + Clone
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN { > RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
#[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() } #[inline(always)] fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(crate::stdlib::any::type_name::<$par>()),*].into_boxed_slice() } #[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> Box<[&'static str]> { vec![$(std::any::type_name::<$par>()),*].into_boxed_slice() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<Result<RET, Box<EvalAltResult>>>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { crate::stdlib::any::type_name::<Result<RET, Box<EvalAltResult>>>() } #[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { std::any::type_name::<Result<RET, Box<EvalAltResult>>>() }
#[inline(always)] fn into_callable_function(self) -> CallableFunction { #[inline(always)] fn into_callable_function(self) -> CallableFunction {
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| { CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types! // The arguments are assumed to be of the correct number and types!

View File

@ -61,6 +61,12 @@
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
extern crate alloc; extern crate alloc;
#[cfg(feature = "no_std")]
extern crate no_std_compat as std;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
// Internal modules // Internal modules
mod ast; mod ast;
@ -82,13 +88,12 @@ mod parser;
pub mod plugin; pub mod plugin;
mod result; mod result;
mod scope; mod scope;
mod stdlib;
mod syntax; mod syntax;
mod token; mod token;
mod r#unsafe; mod r#unsafe;
mod utils; mod utils;
type RhaiResult = stdlib::result::Result<Dynamic, stdlib::boxed::Box<EvalAltResult>>; type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
/// The system integer type. It is defined as [`i64`]. /// The system integer type. It is defined as [`i64`].
/// ///
@ -104,20 +109,18 @@ pub type INT = i64;
pub type INT = i32; pub type INT = i32;
/// The system floating-point type. It is defined as [`f64`]. /// The system floating-point type. It is defined as [`f64`].
/// Not available under `no_float`.
/// ///
/// If the `f32_float` feature is enabled, this will be [`i32`] instead. /// If the `f32_float` feature is enabled, this will be [`i32`] instead.
///
/// Not available under `no_float`.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
#[cfg(not(feature = "f32_float"))] #[cfg(not(feature = "f32_float"))]
pub type FLOAT = f64; pub type FLOAT = f64;
/// The system floating-point type. /// The system floating-point type.
/// It is defined as [`f32`] since the `f32_float` feature is used. /// It is defined as [`f32`] since the `f32_float` feature is used.
/// Not available under `no_float`.
/// ///
/// If the `f32_float` feature is not used, this will be `f64` instead. /// If the `f32_float` feature is not used, this will be `f64` instead.
///
/// Not available under `no_float`.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
#[cfg(feature = "f32_float")] #[cfg(feature = "f32_float")]
pub type FLOAT = f32; pub type FLOAT = f32;
@ -180,16 +183,14 @@ pub use fn_args::FuncArgs;
pub use ast::ScriptFnMetadata; pub use ast::ScriptFnMetadata;
/// Variable-sized array of [`Dynamic`] values. /// Variable-sized array of [`Dynamic`] values.
///
/// Not available under `no_index`. /// Not available under `no_index`.
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub type Array = stdlib::vec::Vec<Dynamic>; pub type Array = Vec<Dynamic>;
/// Hash map of [`Dynamic`] values with [`ImmutableString`] keys. /// Hash map of [`Dynamic`] values with [`ImmutableString`] keys.
///
/// Not available under `no_object`. /// Not available under `no_object`.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub type Map = stdlib::collections::BTreeMap<Identifier, Dynamic>; pub type Map = std::collections::BTreeMap<Identifier, Dynamic>;
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
pub use module::ModuleResolver; pub use module::ModuleResolver;

View File

@ -4,23 +4,22 @@ use crate::ast::{FnAccess, Ident};
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync}; use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync};
use crate::fn_register::RegisterNativeFunction; use crate::fn_register::RegisterNativeFunction;
use crate::stdlib::{
any::TypeId,
boxed::Box,
collections::{BTreeMap, BTreeSet},
fmt,
iter::empty,
num::NonZeroUsize,
ops::{Add, AddAssign, Deref, DerefMut},
string::String,
vec::Vec,
};
use crate::token::Token; use crate::token::Token;
use crate::utils::IdentifierBuilder; use crate::utils::IdentifierBuilder;
use crate::{ use crate::{
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, EvalAltResult, Identifier, calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, EvalAltResult, Identifier,
ImmutableString, NativeCallContext, Position, Shared, StaticVec, ImmutableString, NativeCallContext, Position, Shared, StaticVec,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::TypeId,
collections::{BTreeMap, BTreeSet},
fmt,
iter::empty,
num::NonZeroUsize,
ops::{Add, AddAssign, Deref, DerefMut},
};
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -73,7 +72,7 @@ impl FuncInfo {
let mut sig = format!("{}(", self.name); let mut sig = format!("{}(", self.name);
if !self.param_names.is_empty() { if !self.param_names.is_empty() {
let mut params: crate::stdlib::vec::Vec<String> = let mut params: std::vec::Vec<String> =
self.param_names.iter().map(|s| s.as_str().into()).collect(); self.param_names.iter().map(|s| s.as_str().into()).collect();
let return_type = params.pop().unwrap_or_else(|| "()".into()); let return_type = params.pop().unwrap_or_else(|| "()".into());
sig.push_str(&params.join(", ")); sig.push_str(&params.join(", "));
@ -198,7 +197,7 @@ impl fmt::Debug for Module {
&self &self
.functions .functions
.values() .values()
.map(|f| crate::stdlib::string::ToString::to_string(&f.func)) .map(|f| std::string::ToString::to_string(&f.func))
.collect::<BTreeSet<_>>(), .collect::<BTreeSet<_>>(),
); );
} }
@ -1231,7 +1230,7 @@ impl Module {
&mut self, &mut self,
filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool, filter: impl Fn(FnNamespace, FnAccess, &str, usize) -> bool,
) -> &mut Self { ) -> &mut Self {
self.functions = crate::stdlib::mem::take(&mut self.functions) self.functions = std::mem::take(&mut self.functions)
.into_iter() .into_iter()
.filter(|(_, f)| { .filter(|(_, f)| {
if f.func.is_script() { if f.func.is_script() {

View File

@ -1,5 +1,7 @@
use crate::stdlib::{boxed::Box, ops::AddAssign, vec::Vec};
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
use std::ops::AddAssign;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// [Module] resolution service that holds a collection of module resolvers, /// [Module] resolution service that holds a collection of module resolvers,
/// to be searched in sequential order. /// to be searched in sequential order.

View File

@ -1,5 +1,6 @@
use crate::stdlib::boxed::Box;
use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// Empty/disabled [module][Module] resolution service that acts as a dummy. /// Empty/disabled [module][Module] resolution service that acts as a dummy.
/// ///

View File

@ -1,10 +1,11 @@
use crate::stdlib::{ use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
boxed::Box, #[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
collections::BTreeMap, collections::BTreeMap,
io::Error as IoError, io::Error as IoError,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
pub const RHAI_SCRIPT_EXTENSION: &str = "rhai"; pub const RHAI_SCRIPT_EXTENSION: &str = "rhai";
@ -45,9 +46,9 @@ pub struct FileModuleResolver {
cache_enabled: bool, cache_enabled: bool,
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
cache: crate::stdlib::cell::RefCell<BTreeMap<PathBuf, Shared<Module>>>, cache: std::cell::RefCell<BTreeMap<PathBuf, Shared<Module>>>,
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
cache: crate::stdlib::sync::RwLock<BTreeMap<PathBuf, Shared<Module>>>, cache: std::sync::RwLock<BTreeMap<PathBuf, Shared<Module>>>,
} }
impl Default for FileModuleResolver { impl Default for FileModuleResolver {

View File

@ -1,6 +1,7 @@
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::stdlib::boxed::Box;
use crate::{Engine, EvalAltResult, Module, Position, Shared, AST}; use crate::{Engine, EvalAltResult, Module, Position, Shared, AST};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
mod dummy; mod dummy;
pub use dummy::DummyModuleResolver; pub use dummy::DummyModuleResolver;

View File

@ -1,5 +1,7 @@
use crate::stdlib::{boxed::Box, collections::BTreeMap, ops::AddAssign};
use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Identifier, Module, ModuleResolver, Position, Shared};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{collections::BTreeMap, ops::AddAssign};
/// A static [module][Module] resolution service that serves [modules][Module] added into it. /// A static [module][Module] resolution service that serves [modules][Module] added into it.
/// ///

View File

@ -5,21 +5,19 @@ use crate::dynamic::AccessMode;
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF}; use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
use crate::fn_builtin::get_builtin_binary_op_fn; use crate::fn_builtin::get_builtin_binary_op_fn;
use crate::parser::map_dynamic_to_expr; use crate::parser::map_dynamic_to_expr;
use crate::stdlib::{
any::TypeId,
boxed::Box,
hash::{Hash, Hasher},
iter::empty,
mem,
string::{String, ToString},
vec,
vec::Vec,
};
use crate::utils::get_hasher; use crate::utils::get_hasher;
use crate::{ use crate::{
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, ImmutableString, Module, calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, ImmutableString, Module,
Position, Scope, StaticVec, AST, Position, Scope, StaticVec, AST,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::TypeId,
hash::{Hash, Hasher},
iter::empty,
mem,
};
/// Level of optimization performed. /// Level of optimization performed.
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)] #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
@ -947,7 +945,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
"" ""
}; };
if let Some(result) = call_fn_with_constant_arguments(&state, x.name.as_ref(), arg_values.as_mut()) if let Some(result) = call_fn_with_constant_arguments(&state, x.name.as_ref(), &mut arg_values)
.or_else(|| { .or_else(|| {
if !arg_for_type_of.is_empty() { if !arg_for_type_of.is_empty() {
// Handle `type_of()` // Handle `type_of()`

View File

@ -1,8 +1,9 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{format, string::String};
use crate::{def_package, EvalAltResult, Position, INT}; use crate::{def_package, EvalAltResult, Position, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;

View File

@ -3,8 +3,10 @@
use crate::engine::OP_EQUALS; use crate::engine::OP_EQUALS;
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{any::TypeId, boxed::Box, cmp::Ordering, mem, string::ToString};
use crate::{def_package, Array, Dynamic, EvalAltResult, FnPtr, NativeCallContext, Position, INT}; use crate::{def_package, Array, Dynamic, EvalAltResult, FnPtr, NativeCallContext, Position, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::TypeId, cmp::Ordering, mem};
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, { def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
combine_with_exported_module!(lib, "array", array_functions); combine_with_exported_module!(lib, "array", array_functions);

View File

@ -1,5 +1,7 @@
use crate::plugin::*; use crate::plugin::*;
use crate::{def_package, FnPtr, ImmutableString, NativeCallContext}; use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, { def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions); combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
@ -34,7 +36,8 @@ mod fn_ptr_functions {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array { fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
use crate::{ast::ScriptFnDef, stdlib::collections::BTreeSet, Array, Identifier, Map}; use crate::{ast::ScriptFnDef, Array, Identifier, Map};
use std::collections::BTreeSet;
// Create a metadata record for a function. // Create a metadata record for a function.
fn make_metadata( fn make_metadata(

View File

@ -1,15 +1,17 @@
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::stdlib::{boxed::Box, ops::Range};
use crate::{def_package, EvalAltResult, INT}; use crate::{def_package, EvalAltResult, INT};
use std::ops::Range;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
use crate::stdlib::string::ToString; use std::string::ToString;
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
use num_traits::{CheckedAdd as Add, CheckedSub as Sub}; use num_traits::{CheckedAdd as Add, CheckedSub as Sub};
#[cfg(feature = "unchecked")] #[cfg(feature = "unchecked")]
use crate::stdlib::ops::{Add, Sub}; use std::ops::{Add, Sub};
fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> { fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> {
Ok(from..to) Ok(from..to)
@ -207,7 +209,7 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
pub fn new(from: Decimal, to: Decimal, step: Decimal) -> Result<Self, Box<EvalAltResult>> { pub fn new(from: Decimal, to: Decimal, step: Decimal) -> Result<Self, Box<EvalAltResult>> {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
if step.is_zero() { if step.is_zero() {
use crate::stdlib::string::ToString; use std::string::ToString;
return EvalAltResult::ErrorInFunctionCall("range".to_string(), "".to_string(), return EvalAltResult::ErrorInFunctionCall("range".to_string(), "".to_string(),
Box::new(EvalAltResult::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE)), Box::new(EvalAltResult::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE)),
@ -251,7 +253,7 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
} }
} }
impl crate::stdlib::iter::FusedIterator for StepDecimalRange {} impl std::iter::FusedIterator for StepDecimalRange {}
lib.set_iterator::<StepDecimalRange>(); lib.set_iterator::<StepDecimalRange>();

View File

@ -2,6 +2,8 @@
use crate::def_package; use crate::def_package;
use crate::plugin::*; use crate::plugin::*;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(any( #[cfg(any(
not(feature = "no_float"), not(feature = "no_float"),

View File

@ -3,6 +3,8 @@
use crate::engine::OP_EQUALS; use crate::engine::OP_EQUALS;
use crate::plugin::*; use crate::plugin::*;
use crate::{def_package, Dynamic, ImmutableString, Map, INT}; use crate::{def_package, Dynamic, ImmutableString, Map, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;

View File

@ -2,6 +2,8 @@
use crate::plugin::*; use crate::plugin::*;
use crate::{def_package, Position, INT}; use crate::{def_package, Position, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
@ -9,9 +11,6 @@ use crate::FLOAT;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::result::EvalAltResult; use crate::result::EvalAltResult;
#[cfg(not(feature = "no_float"))]
use crate::stdlib::format;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use num_traits::Float; use num_traits::Float;
@ -194,16 +193,16 @@ mod float_functions {
#[rhai_fn(name = "E")] #[rhai_fn(name = "E")]
pub fn e() -> FLOAT { pub fn e() -> FLOAT {
#[cfg(not(feature = "f32_float"))] #[cfg(not(feature = "f32_float"))]
return crate::stdlib::f64::consts::E; return std::f64::consts::E;
#[cfg(feature = "f32_float")] #[cfg(feature = "f32_float")]
return crate::stdlib::f32::consts::E; return std::f32::consts::E;
} }
#[rhai_fn(name = "PI")] #[rhai_fn(name = "PI")]
pub fn pi() -> FLOAT { pub fn pi() -> FLOAT {
#[cfg(not(feature = "f32_float"))] #[cfg(not(feature = "f32_float"))]
return crate::stdlib::f64::consts::PI; return std::f64::consts::PI;
#[cfg(feature = "f32_float")] #[cfg(feature = "f32_float")]
return crate::stdlib::f32::consts::PI; return std::f32::consts::PI;
} }
pub fn to_radians(x: FLOAT) -> FLOAT { pub fn to_radians(x: FLOAT) -> FLOAT {
x.to_radians() x.to_radians()
@ -304,11 +303,11 @@ mod float_functions {
#[cfg(feature = "decimal")] #[cfg(feature = "decimal")]
#[export_module] #[export_module]
mod decimal_functions { mod decimal_functions {
use crate::stdlib::convert::TryFrom;
use rust_decimal::{ use rust_decimal::{
prelude::{FromStr, RoundingStrategy}, prelude::{FromStr, RoundingStrategy},
Decimal, Decimal,
}; };
use std::convert::TryFrom;
#[rhai_fn(name = "floor", get = "floor")] #[rhai_fn(name = "floor", get = "floor")]
pub fn floor(x: Decimal) -> Decimal { pub fn floor(x: Decimal) -> Decimal {

View File

@ -3,6 +3,8 @@ use super::fn_basic::BasicFnPackage;
use super::iter_basic::BasicIteratorPackage; use super::iter_basic::BasicIteratorPackage;
use super::logic::LogicPackage; use super::logic::LogicPackage;
use super::string_basic::BasicStringPackage; use super::string_basic::BasicStringPackage;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use crate::def_package; use crate::def_package;

View File

@ -7,6 +7,8 @@ use super::pkg_core::CorePackage;
use super::string_more::MoreStringPackage; use super::string_more::MoreStringPackage;
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
use super::time_basic::BasicTimePackage; use super::time_basic::BasicTimePackage;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use crate::def_package; use crate::def_package;

View File

@ -1,8 +1,9 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{format, string::ToString};
use crate::{def_package, FnPtr}; use crate::{def_package, FnPtr};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -69,10 +70,6 @@ mod print_debug_functions {
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
pub mod float_functions { pub mod float_functions {
#[cfg(feature = "no_std")]
#[cfg(not(feature = "no_float"))]
use num_traits::Float;
use crate::ast::FloatWrapper; use crate::ast::FloatWrapper;
#[rhai_fn(name = "print", name = "to_string")] #[rhai_fn(name = "print", name = "to_string")]
@ -106,7 +103,7 @@ mod print_debug_functions {
)] )]
pub fn format_array(ctx: NativeCallContext, array: &mut Array) -> ImmutableString { pub fn format_array(ctx: NativeCallContext, array: &mut Array) -> ImmutableString {
let len = array.len(); let len = array.len();
let mut result = crate::stdlib::string::String::with_capacity(len * 5 + 2); let mut result = std::string::String::with_capacity(len * 5 + 2);
result.push_str("["); result.push_str("[");
array.iter_mut().enumerate().for_each(|(i, x)| { array.iter_mut().enumerate().for_each(|(i, x)| {
@ -133,7 +130,7 @@ mod print_debug_functions {
)] )]
pub fn format_map(ctx: NativeCallContext, map: &mut Map) -> ImmutableString { pub fn format_map(ctx: NativeCallContext, map: &mut Map) -> ImmutableString {
let len = map.len(); let len = map.len();
let mut result = crate::stdlib::string::String::with_capacity(len * 5 + 3); let mut result = std::string::String::with_capacity(len * 5 + 3);
result.push_str("#{"); result.push_str("#{");
map.iter_mut().enumerate().for_each(|(i, (k, v))| { map.iter_mut().enumerate().for_each(|(i, (k, v))| {

View File

@ -1,10 +1,10 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::{
any::TypeId, boxed::Box, format, mem, string::String, string::ToString, vec::Vec,
};
use crate::{def_package, Dynamic, ImmutableString, StaticVec, INT}; use crate::{def_package, Dynamic, ImmutableString, StaticVec, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::TypeId, mem};
use super::string_basic::{print_with_func, FUNC_TO_STRING}; use super::string_basic::{print_with_func, FUNC_TO_STRING};
@ -422,7 +422,6 @@ mod string_functions {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub mod arrays { pub mod arrays {
use crate::stdlib::vec;
use crate::{Array, ImmutableString}; use crate::{Array, ImmutableString};
#[rhai_fn(name = "split")] #[rhai_fn(name = "split")]

View File

@ -2,14 +2,15 @@
use super::{arithmetic::make_err as make_arithmetic_err, math_basic::MAX_INT}; use super::{arithmetic::make_err as make_arithmetic_err, math_basic::MAX_INT};
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::boxed::Box;
use crate::{def_package, Dynamic, EvalAltResult, INT}; use crate::{def_package, Dynamic, EvalAltResult, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
use crate::stdlib::time::{Duration, Instant}; use std::time::{Duration, Instant};
#[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))] #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))]
use instant::{Duration, Instant}; use instant::{Duration, Instant};

View File

@ -1,12 +1,13 @@
//! Module containing error definitions for the parsing process. //! Module containing error definitions for the parsing process.
use crate::stdlib::{
boxed::Box,
error::Error,
fmt,
string::{String, ToString},
};
use crate::{EvalAltResult, Position}; use crate::{EvalAltResult, Position};
#[cfg(feature = "no_std")]
use core_error::Error;
#[cfg(not(feature = "no_std"))]
use std::error::Error;
use std::fmt;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// _(INTERNALS)_ Error encountered when tokenizing the script text. /// _(INTERNALS)_ Error encountered when tokenizing the script text.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.

View File

@ -9,17 +9,6 @@ use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS};
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::optimize::optimize_into_ast; use crate::optimize::optimize_into_ast;
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::stdlib::{
boxed::Box,
collections::BTreeMap,
format,
hash::{Hash, Hasher},
iter::empty,
num::{NonZeroU8, NonZeroUsize},
string::ToString,
vec,
vec::Vec,
};
use crate::syntax::{CustomSyntax, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT}; use crate::syntax::{CustomSyntax, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
use crate::token::{ use crate::token::{
is_keyword_function, is_valid_identifier, Token, TokenStream, TokenizerControl, is_keyword_function, is_valid_identifier, Token, TokenStream, TokenizerControl,
@ -29,6 +18,14 @@ use crate::{
calc_fn_hash, Dynamic, Engine, Identifier, LexError, ParseError, ParseErrorType, Position, calc_fn_hash, Dynamic, Engine, Identifier, LexError, ParseError, ParseErrorType, Position,
Scope, Shared, StaticVec, AST, Scope, Shared, StaticVec, AST,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
collections::BTreeMap,
hash::{Hash, Hasher},
iter::empty,
num::{NonZeroU8, NonZeroUsize},
};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
@ -381,7 +378,7 @@ fn parse_fn_call(
(Token::RightParen, _) => { (Token::RightParen, _) => {
eat_token(input, Token::RightParen); eat_token(input, Token::RightParen);
let hash = if let Some(modules) = namespace.as_mut() { let hash = if let Some(ref mut modules) = namespace {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
modules.set_index(state.find_module(&modules[0].name)); modules.set_index(state.find_module(&modules[0].name));
@ -2501,7 +2498,7 @@ fn parse_stmt(
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
let comments = { let comments = {
let mut comments: StaticVec<crate::stdlib::string::String> = Default::default(); let mut comments: StaticVec<std::string::String> = Default::default();
let mut comments_pos = Position::NONE; let mut comments_pos = Position::NONE;
// Handle doc-comments. // Handle doc-comments.
@ -2756,7 +2753,7 @@ fn parse_fn(
mut settings: ParseSettings, mut settings: ParseSettings,
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(feature = "metadata")] #[cfg(feature = "metadata")]
comments: StaticVec<crate::stdlib::string::String>, comments: StaticVec<std::string::String>,
) -> Result<ScriptFnDef, ParseError> { ) -> Result<ScriptFnDef, ParseError> {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
settings.ensure_level_within_max_limit(state.max_expr_depth)?; settings.ensure_level_within_max_limit(state.max_expr_depth)?;

View File

@ -1,11 +1,13 @@
//! Module defining macros for developing _plugins_. //! Module defining macros for developing _plugins_.
pub use crate::fn_native::{CallableFunction, FnCallArgs}; pub use crate::fn_native::{CallableFunction, FnCallArgs};
pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString};
pub use crate::{ pub use crate::{
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
NativeCallContext, Position, NativeCallContext, Position,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
pub use std::{any::TypeId, mem};
pub type RhaiResult = Result<Dynamic, Box<EvalAltResult>>; pub type RhaiResult = Result<Dynamic, Box<EvalAltResult>>;
#[cfg(not(features = "no_module"))] #[cfg(not(features = "no_module"))]

View File

@ -1,12 +1,13 @@
//! Module containing error definitions for the evaluation process. //! Module containing error definitions for the evaluation process.
use crate::stdlib::{
boxed::Box,
error::Error,
fmt,
string::{String, ToString},
};
use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT}; use crate::{Dynamic, ImmutableString, ParseErrorType, Position, INT};
#[cfg(feature = "no_std")]
use core_error::Error;
#[cfg(not(feature = "no_std"))]
use std::error::Error;
use std::fmt;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// Evaluation result. /// Evaluation result.
/// ///
@ -335,11 +336,7 @@ impl EvalAltResult {
pub(crate) fn dump_fields(&self, map: &mut crate::Map) { pub(crate) fn dump_fields(&self, map: &mut crate::Map) {
map.insert( map.insert(
"error".into(), "error".into(),
crate::stdlib::format!("{:?}", self) format!("{:?}", self).split('(').next().unwrap().into(),
.split('(')
.next()
.unwrap()
.into(),
); );
match self { match self {

View File

@ -1,8 +1,10 @@
//! Module that defines the [`Scope`] type representing a function call-stack scope. //! Module that defines the [`Scope`] type representing a function call-stack scope.
use crate::dynamic::{AccessMode, Variant}; use crate::dynamic::{AccessMode, Variant};
use crate::stdlib::{borrow::Cow, boxed::Box, iter, vec::Vec};
use crate::{Dynamic, Identifier, StaticVec}; use crate::{Dynamic, Identifier, StaticVec};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{borrow::Cow, iter::Extend};
/// Keep a number of entries inline (since [`Dynamic`] is usually small enough). /// Keep a number of entries inline (since [`Dynamic`] is usually small enough).
const SCOPE_SIZE: usize = 16; const SCOPE_SIZE: usize = 16;
@ -498,7 +500,7 @@ impl<'a> Scope<'a> {
} }
} }
impl<'a, K: Into<Cow<'a, str>>> iter::Extend<(K, Dynamic)> for Scope<'a> { impl<'a, K: Into<Cow<'a, str>>> Extend<(K, Dynamic)> for Scope<'a> {
#[inline(always)] #[inline(always)]
fn extend<T: IntoIterator<Item = (K, Dynamic)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K, Dynamic)>>(&mut self, iter: T) {
iter.into_iter().for_each(|(name, value)| { iter.into_iter().for_each(|(name, value)| {

View File

@ -2,10 +2,12 @@
use super::str::StringSliceDeserializer; use super::str::StringSliceDeserializer;
use crate::dynamic::Union; use crate::dynamic::Union;
use crate::stdlib::{any::type_name, boxed::Box, fmt, string::ToString};
use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, Position}; use crate::{Dynamic, EvalAltResult, ImmutableString, LexError, Position};
use serde::de::{DeserializeSeed, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor}; use serde::de::{DeserializeSeed, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::type_name, fmt};
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;

View File

@ -1,8 +1,10 @@
//! Implementations of [`serde::Deserialize`]. //! Implementations of [`serde::Deserialize`].
use crate::stdlib::{fmt, string::ToString};
use crate::{Dynamic, ImmutableString, INT}; use crate::{Dynamic, ImmutableString, INT};
use serde::de::{Deserialize, Deserializer, Error, Visitor}; use serde::de::{Deserialize, Deserializer, Error, Visitor};
use std::fmt;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -95,8 +97,8 @@ impl<'d> Visitor<'d> for DynamicVisitor {
#[cfg(feature = "no_float")] #[cfg(feature = "no_float")]
#[cfg(feature = "decimal")] #[cfg(feature = "decimal")]
fn visit_f32<E: Error>(self, v: f32) -> Result<Self::Value, E> { fn visit_f32<E: Error>(self, v: f32) -> Result<Self::Value, E> {
use crate::stdlib::convert::TryFrom;
use rust_decimal::Decimal; use rust_decimal::Decimal;
use std::convert::TryFrom;
Decimal::try_from(v) Decimal::try_from(v)
.map(|v| v.into()) .map(|v| v.into())
@ -105,8 +107,8 @@ impl<'d> Visitor<'d> for DynamicVisitor {
#[cfg(feature = "no_float")] #[cfg(feature = "no_float")]
#[cfg(feature = "decimal")] #[cfg(feature = "decimal")]
fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> { fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
use crate::stdlib::convert::TryFrom;
use rust_decimal::Decimal; use rust_decimal::Decimal;
use std::convert::TryFrom;
Decimal::try_from(v) Decimal::try_from(v)
.map(|v| v.into()) .map(|v| v.into())

View File

@ -1,11 +1,8 @@
use crate::stdlib::{
cmp::Ordering,
collections::BTreeMap,
string::{String, ToString},
vec::Vec,
};
use crate::{Engine, AST}; use crate::{Engine, AST};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{cmp::Ordering, collections::BTreeMap};
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]

View File

@ -1,11 +1,13 @@
//! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`]. //! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`].
use crate::stdlib::{boxed::Box, fmt, string::ToString};
use crate::{Dynamic, EvalAltResult, Position, RhaiResult}; use crate::{Dynamic, EvalAltResult, Position, RhaiResult};
use serde::ser::{ use serde::ser::{
Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct, Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct,
}; };
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use std::fmt;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -220,8 +222,8 @@ impl Serializer for &mut DynamicSerializer {
#[cfg(feature = "no_float")] #[cfg(feature = "no_float")]
#[cfg(feature = "decimal")] #[cfg(feature = "decimal")]
{ {
use crate::stdlib::convert::TryFrom;
use rust_decimal::Decimal; use rust_decimal::Decimal;
use std::convert::TryFrom;
Decimal::try_from(v) Decimal::try_from(v)
.map(|v| v.into()) .map(|v| v.into())
@ -236,8 +238,8 @@ impl Serializer for &mut DynamicSerializer {
#[cfg(feature = "no_float")] #[cfg(feature = "no_float")]
#[cfg(feature = "decimal")] #[cfg(feature = "decimal")]
{ {
use crate::stdlib::convert::TryFrom;
use rust_decimal::Decimal; use rust_decimal::Decimal;
use std::convert::TryFrom;
Decimal::try_from(v) Decimal::try_from(v)
.map(|v| v.into()) .map(|v| v.into())
@ -539,7 +541,7 @@ impl SerializeMap for DynamicSerializer {
) -> Result<(), Box<EvalAltResult>> { ) -> Result<(), Box<EvalAltResult>> {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
{ {
let key = crate::stdlib::mem::take(&mut self._key) let key = std::mem::take(&mut self._key)
.take_immutable_string() .take_immutable_string()
.map_err(|typ| { .map_err(|typ| {
EvalAltResult::ErrorMismatchDataType( EvalAltResult::ErrorMismatchDataType(

View File

@ -1,9 +1,10 @@
//! Implementations of [`serde::Serialize`]. //! Implementations of [`serde::Serialize`].
use crate::dynamic::{Union, Variant}; use crate::dynamic::{Union, Variant};
use crate::stdlib::string::ToString;
use crate::{Dynamic, ImmutableString}; use crate::{Dynamic, ImmutableString};
use serde::ser::{Serialize, Serializer}; use serde::ser::{Serialize, Serializer};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use serde::ser::SerializeMap; use serde::ser::SerializeMap;

View File

@ -1,8 +1,10 @@
//! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`]. //! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`].
use crate::stdlib::{any::type_name, boxed::Box};
use crate::{EvalAltResult, Position}; use crate::{EvalAltResult, Position};
use serde::de::{Deserializer, Visitor}; use serde::de::{Deserializer, Visitor};
use std::any::type_name;
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// Deserializer for `ImmutableString`. /// Deserializer for `ImmutableString`.
pub struct StringSliceDeserializer<'a> { pub struct StringSliceDeserializer<'a> {

View File

@ -1,32 +0,0 @@
//! Helper module which defines most of the needed features from `std` for `no-std` builds.
#[cfg(feature = "no_std")]
mod inner {
pub use core::{
any, arch, array, ascii, cell, char, clone, cmp, convert, default, f32, f64, ffi, fmt,
future, hash, hint, i16, i32, i64, i8, isize, iter, marker, mem, num, ops, option, panic,
pin, prelude, ptr, result, slice, str, task, time, u16, u32, u64, u8, usize,
};
#[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))]
pub use core::{i128, u128};
#[cfg(feature = "sync")]
pub use alloc::sync;
pub use alloc::{borrow, boxed, format, rc, string, vec};
pub use core_error as error;
pub mod collections {
pub use alloc::collections::btree_map::BTreeMap;
pub use alloc::collections::btree_set::BTreeSet;
}
}
#[cfg(not(feature = "no_std"))]
mod inner {
pub use std::*;
}
pub use self::inner::*;

View File

@ -3,12 +3,13 @@
use crate::ast::Expr; use crate::ast::Expr;
use crate::engine::EvalContext; use crate::engine::EvalContext;
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::stdlib::{boxed::Box, format, string::ToString};
use crate::token::{is_valid_identifier, Token}; use crate::token::{is_valid_identifier, Token};
use crate::{ use crate::{
Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared, Engine, Identifier, ImmutableString, LexError, ParseError, Position, RhaiResult, Shared,
StaticVec, StaticVec,
}; };
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
pub const MARKER_EXPR: &str = "$expr$"; pub const MARKER_EXPR: &str = "$expr$";
pub const MARKER_BLOCK: &str = "$block$"; pub const MARKER_BLOCK: &str = "$block$";

View File

@ -4,18 +4,19 @@ use crate::engine::{
Precedence, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL, Precedence, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL,
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_THIS, KEYWORD_TYPE_OF,
}; };
use crate::stdlib::{ use crate::{Engine, LexError, StaticVec, INT};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
borrow::Cow, borrow::Cow,
cell::Cell, cell::Cell,
char, fmt, format, char, fmt,
iter::{FusedIterator, Peekable}, iter::{FusedIterator, Peekable},
num::NonZeroUsize, num::NonZeroUsize,
ops::{Add, AddAssign}, ops::{Add, AddAssign},
rc::Rc, rc::Rc,
str::{Chars, FromStr}, str::{Chars, FromStr},
string::{String, ToString},
}; };
use crate::{Engine, LexError, StaticVec, INT};
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::{ast::FloatWrapper, FLOAT}; use crate::{ast::FloatWrapper, FLOAT};

View File

@ -1,9 +1,10 @@
//! A helper module containing unsafe utility functions. //! A helper module containing unsafe utility functions.
use crate::dynamic::Variant; use crate::dynamic::Variant;
use crate::stdlib::{ #[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::{Any, TypeId}, any::{Any, TypeId},
boxed::Box,
mem, ptr, mem, ptr,
}; };

View File

@ -1,20 +1,19 @@
//! Module containing various utility types and functions. //! Module containing various utility types and functions.
use crate::fn_native::{shared_make_mut, shared_take}; use crate::fn_native::{shared_make_mut, shared_take};
use crate::stdlib::{ use crate::{Identifier, Shared};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
any::TypeId, any::TypeId,
borrow::Borrow, borrow::Borrow,
boxed::Box,
cmp::Ordering, cmp::Ordering,
fmt, fmt,
fmt::{Debug, Display},
hash::{BuildHasher, Hash, Hasher}, hash::{BuildHasher, Hash, Hasher},
iter::FromIterator, iter::FromIterator,
ops::{Add, AddAssign, Deref, Sub, SubAssign}, ops::{Add, AddAssign, Deref, Sub, SubAssign},
str::FromStr, str::FromStr,
string::{String, ToString},
}; };
use crate::{Identifier, Shared};
/// A hasher that only takes one single [`u64`] and returns it as a hash key. /// A hasher that only takes one single [`u64`] and returns it as a hash key.
/// ///
@ -251,17 +250,17 @@ impl<'a> FromIterator<String> for ImmutableString {
} }
} }
impl Display for ImmutableString { impl fmt::Display for ImmutableString {
#[inline(always)] #[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(self.0.as_str(), f) fmt::Display::fmt(self.0.as_str(), f)
} }
} }
impl Debug for ImmutableString { impl fmt::Debug for ImmutableString {
#[inline(always)] #[inline(always)]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Debug::fmt(self.0.as_str(), f) fmt::Debug::fmt(self.0.as_str(), f)
} }
} }
@ -631,7 +630,7 @@ impl ImmutableString {
/// yet interned. /// yet interned.
#[derive(Debug, Clone, Default, Hash)] #[derive(Debug, Clone, Default, Hash)]
pub struct IdentifierBuilder( pub struct IdentifierBuilder(
#[cfg(feature = "no_smartstring")] crate::stdlib::collections::BTreeSet<Identifier>, #[cfg(feature = "no_smartstring")] std::collections::BTreeSet<Identifier>,
); );
impl IdentifierBuilder { impl IdentifierBuilder {