Merge pull request #301 from schungx/master

Fix features.
This commit is contained in:
Stephen Chung 2020-11-28 17:37:22 +08:00 committed by GitHub
commit 7881f2bde2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 227 additions and 185 deletions

View File

@ -32,6 +32,7 @@ jobs:
- "--features no_module" - "--features no_module"
- "--features no_closure" - "--features no_closure"
- "--features unicode-xid-ident" - "--features unicode-xid-ident"
- "--features sync,no_function,no_float,no_optimize,no_module,no_closure,serde,unchecked"
toolchain: [stable] toolchain: [stable]
experimental: [false] experimental: [false]
include: include:

View File

@ -6,7 +6,7 @@ members = [
[package] [package]
name = "rhai" name = "rhai"
version = "0.19.6" version = "0.19.7"
edition = "2018" edition = "2018"
authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"] authors = ["Jonathan Turner", "Lukáš Hozda", "Stephen Chung", "jhwgh1968"]
description = "Embedded scripting for Rust" description = "Embedded scripting for Rust"

View File

@ -1,6 +1,10 @@
Rhai Release Notes Rhai Release Notes
================== ==================
Version 0.19.7
==============
Version 0.19.6 Version 0.19.6
============== ==============
@ -45,6 +49,7 @@ Enhancements
------------ ------------
* New constants under `Dynamic` including `UNIT`, `TRUE`, `FALSE`, `ZERO`, `ONE` etc. * New constants under `Dynamic` including `UNIT`, `TRUE`, `FALSE`, `ZERO`, `ONE` etc.
* Floating-point numbers ending with a decimal point without a trailing `0` are supported.
Version 0.19.5 Version 0.19.5

View File

@ -1,5 +1,5 @@
{ {
"version": "0.19.6", "version": "0.19.7",
"repoHome": "https://github.com/jonathandturner/rhai/blob/master", "repoHome": "https://github.com/jonathandturner/rhai/blob/master",
"repoTree": "https://github.com/jonathandturner/rhai/tree/master", "repoTree": "https://github.com/jonathandturner/rhai/tree/master",
"rootUrl": "", "rootUrl": "",

View File

@ -41,7 +41,7 @@ pub enum FnAccess {
} }
impl FnAccess { impl FnAccess {
/// Is this access mode private? /// Is this access mode [private][FnAccess::Private]?
#[inline(always)] #[inline(always)]
pub fn is_private(self) -> bool { pub fn is_private(self) -> bool {
match self { match self {
@ -49,7 +49,7 @@ impl FnAccess {
Self::Public => false, Self::Public => false,
} }
} }
/// Is this access mode public? /// Is this access mode [public][FnAccess::Public]?
#[inline(always)] #[inline(always)]
pub fn is_public(self) -> bool { pub fn is_public(self) -> bool {
match self { match self {
@ -151,6 +151,7 @@ impl AST {
&mut self.0 &mut self.0
} }
/// Get the internal shared [`Module`] containing all script-defined functions. /// Get the internal shared [`Module`] containing all script-defined functions.
#[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub(crate) fn shared_lib(&self) -> Shared<Module> { pub(crate) fn shared_lib(&self) -> Shared<Module> {
@ -482,7 +483,7 @@ impl AST {
#[inline(always)] #[inline(always)]
pub fn iter_functions<'a>( pub fn iter_functions<'a>(
&'a self, &'a self,
) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, Shared<ScriptFnDef>)> + 'a { ) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, &ScriptFnDef)> + 'a {
self.1.iter_script_fn() self.1.iter_script_fn()
} }
/// Clear all function definitions in the [`AST`]. /// Clear all function definitions in the [`AST`].
@ -528,7 +529,12 @@ impl AsRef<Module> for AST {
} }
} }
/// An identifier containing a string name and a position. /// _(INTERNALS)_ An identifier containing a [string][String] name and a [position][Position].
/// Exported under the `internals` feature only.
///
/// ## WARNING
///
/// This type is volatile and may change.
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct Ident { pub struct Ident {
pub name: String, pub name: String,
@ -542,7 +548,12 @@ impl Ident {
} }
} }
/// An identifier containing an immutable name and a position. /// _(INTERNALS)_ An identifier containing an [immutable string][ImmutableString] name and a [position][Position].
/// Exported under the `internals` feature only.
///
/// ## WARNING
///
/// This type is volatile and may change.
#[derive(Debug, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct IdentX { pub struct IdentX {
pub name: ImmutableString, pub name: ImmutableString,
@ -650,7 +661,7 @@ impl Stmt {
_ => false, _ => false,
} }
} }
/// Get the [`Position`] of this statement. /// Get the [position][`Position`] of this statement.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::Noop(pos) Self::Noop(pos)
@ -679,7 +690,7 @@ impl Stmt {
Self::Share(x) => x.pos, Self::Share(x) => x.pos,
} }
} }
/// Override the [`Position`] of this statement. /// Override the [position][`Position`] of this statement.
pub fn set_position(&mut self, new_pos: Position) -> &mut Self { pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
match self { match self {
Self::Noop(pos) Self::Noop(pos)
@ -742,6 +753,8 @@ impl Stmt {
} }
} }
/// Is this statement _pure_? /// Is this statement _pure_?
///
/// A pure statement has no side effects.
pub fn is_pure(&self) -> bool { pub fn is_pure(&self) -> bool {
match self { match self {
Self::Noop(_) => true, Self::Noop(_) => true,
@ -967,7 +980,7 @@ impl Expr {
_ => None, _ => None,
} }
} }
/// Get the [`Position`] of the expression. /// Get the [position][`Position`] of the expression.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::Expr(x) => x.position(), Self::Expr(x) => x.position(),
@ -997,7 +1010,7 @@ impl Expr {
Self::Custom(_, pos) => *pos, Self::Custom(_, pos) => *pos,
} }
} }
/// Override the [`Position`] of the expression. /// Override the [position][`Position`] of the expression.
pub fn set_position(&mut self, new_pos: Position) -> &mut Self { pub fn set_position(&mut self, new_pos: Position) -> &mut Self {
match self { match self {
Self::Expr(x) => { Self::Expr(x) => {
@ -1089,7 +1102,7 @@ impl Expr {
_ => false, _ => false,
} }
} }
/// Is a particular token allowed as a postfix operator to this expression? /// Is a particular [token][Token] allowed as a postfix operator to this expression?
pub fn is_valid_postfix(&self, token: &Token) -> bool { pub fn is_valid_postfix(&self, token: &Token) -> bool {
match self { match self {
Self::Expr(x) => x.is_valid_postfix(token), Self::Expr(x) => x.is_valid_postfix(token),

View File

@ -43,7 +43,7 @@ mod private {
/// Trait to represent any type. /// Trait to represent any type.
/// ///
/// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type. /// Currently, [`Variant`] is not [`Send`] nor [`Sync`], so it can practically be any type.
/// Turn on the [`Sync`] feature to restrict it to only types that implement [`Send`] `+` [`Sync`]. /// Turn on the `sync` feature to restrict it to only types that implement [`Send`] `+` [`Sync`].
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub trait Variant: Any + private::Sealed { pub trait Variant: Any + private::Sealed {
/// Convert this [`Variant`] trait object to [`&dyn Any`][Any]. /// Convert this [`Variant`] trait object to [`&dyn Any`][Any].
@ -268,7 +268,7 @@ impl Dynamic {
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
pub fn type_id(&self) -> TypeId { pub fn type_id(&self) -> TypeId {
match &self.0 { match &self.0 {
@ -301,7 +301,7 @@ impl Dynamic {
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
pub fn type_name(&self) -> &'static str { pub fn type_name(&self) -> &'static str {
match &self.0 { match &self.0 {
@ -654,7 +654,7 @@ impl Dynamic {
Self(Union::Variant(Box::new(boxed))) Self(Union::Variant(Box::new(boxed)))
} }
/// Turn the [`Dynamic`] value into a shared [`Dynamic`] value backed by an [`Rc`][std::rc::Rc]`<`[`RefCell`][std::cell::RefCell]`<`[`Dynamic`]`>>` /// Turn the [`Dynamic`] value into a shared [`Dynamic`] value backed by an [`Rc`][std::rc::Rc]`<`[`RefCell`][std::cell::RefCell]`<`[`Dynamic`]`>>`
/// or [`Arc`][std::sync::Arc]`<`[`RwLock`][std::sync::RwLock]`<`[`Dynamic`]`>>` depending on the [`Sync`] feature. /// or [`Arc`][std::sync::Arc]`<`[`RwLock`][std::sync::RwLock]`<`[`Dynamic`]`>>` depending on the `sync` feature.
/// ///
/// Shared [`Dynamic`] values are relatively cheap to clone as they simply increment the /// Shared [`Dynamic`] values are relatively cheap to clone as they simply increment the
/// reference counts. /// reference counts.
@ -686,7 +686,7 @@ impl Dynamic {
/// ///
/// # Panics or Deadlocks /// # Panics or Deadlocks
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
/// ///
/// These normally shouldn't occur since most operations in Rhai is single-threaded. /// These normally shouldn't occur since most operations in Rhai is single-threaded.
@ -819,7 +819,7 @@ impl Dynamic {
/// Panics if the cast fails (e.g. the type of the actual value is not the /// Panics if the cast fails (e.g. the type of the actual value is not the
/// same as the specified type). /// same as the specified type).
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
/// ///
/// These normally shouldn't occur since most operations in Rhai is single-threaded. /// These normally shouldn't occur since most operations in Rhai is single-threaded.
@ -900,7 +900,7 @@ impl Dynamic {
/// ///
/// ## 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`].
#[inline(always)] #[inline(always)]
@ -924,7 +924,7 @@ impl Dynamic {
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
#[inline(always)] #[inline(always)]
pub fn read_lock<T: Variant + Clone>(&self) -> Option<DynamicReadLock<T>> { pub fn read_lock<T: Variant + Clone>(&self) -> Option<DynamicReadLock<T>> {
@ -956,7 +956,7 @@ impl Dynamic {
/// ///
/// # Panics or Deadlocks When Value is Shared /// # Panics or Deadlocks When Value is Shared
/// ///
/// Under the [`Sync`] feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1). /// Under the `sync` feature, this call may deadlock, or [panic](https://doc.rust-lang.org/std/sync/struct.RwLock.html#panics-1).
/// Otherwise, this call panics if the data is currently borrowed for write. /// Otherwise, this call panics if the data is currently borrowed for write.
#[inline(always)] #[inline(always)]
pub fn write_lock<T: Variant + Clone>(&mut self) -> Option<DynamicWriteLock<T>> { pub fn write_lock<T: Variant + Clone>(&mut self) -> Option<DynamicWriteLock<T>> {

View File

@ -40,7 +40,7 @@ use crate::Map;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
/// _(INTERNALS)_ A stack of imported modules. /// _(INTERNALS)_ A stack of imported [modules][Module].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -49,21 +49,22 @@ pub const TYPICAL_MAP_SIZE: usize = 8; // Small maps are typical
// //
// # Implementation Notes // # Implementation Notes
// //
// We cannot use &str or Cow<str> here because `eval` may load a module and the module name will live beyond // We cannot use &str or Cow<str> here because `eval` may load a [module][Module] and
// the AST of the eval script text. The best we can do is a shared reference. // the module name will live beyond the AST of the eval script text.
// The best we can do is a shared reference.
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct Imports(Option<StaticVec<(ImmutableString, Shared<Module>)>>); pub struct Imports(Option<StaticVec<(ImmutableString, Shared<Module>)>>);
impl Imports { impl Imports {
/// Get the length of this stack of imported modules. /// Get the length of this stack of imported [modules][Module].
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.0.as_ref().map_or(0, StaticVec::len) self.0.as_ref().map_or(0, StaticVec::len)
} }
/// Is this stack of imported modules empty? /// Is this stack of imported [modules][Module] empty?
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.0.as_ref().map_or(true, StaticVec::is_empty) self.0.as_ref().map_or(true, StaticVec::is_empty)
} }
/// Get the imported module at a particular index. /// Get the imported [modules][Module] at a particular index.
pub fn get(&self, index: usize) -> Option<Shared<Module>> { pub fn get(&self, index: usize) -> Option<Shared<Module>> {
self.0 self.0
.as_ref() .as_ref()
@ -71,7 +72,7 @@ impl Imports {
.map(|(_, m)| m) .map(|(_, m)| m)
.cloned() .cloned()
} }
/// Get the index of an imported module by name. /// Get the index of an imported [modules][Module] by name.
pub fn find(&self, name: &str) -> Option<usize> { pub fn find(&self, name: &str) -> Option<usize> {
self.0.as_ref().and_then(|x| { self.0.as_ref().and_then(|x| {
x.iter() x.iter()
@ -81,7 +82,7 @@ impl Imports {
.map(|(index, _)| index) .map(|(index, _)| index)
}) })
} }
/// Push an imported module onto the stack. /// Push an imported [modules][Module] onto the stack.
pub fn push(&mut self, name: impl Into<ImmutableString>, module: impl Into<Shared<Module>>) { pub fn push(&mut self, name: impl Into<ImmutableString>, module: impl Into<Shared<Module>>) {
if self.0.is_none() { if self.0.is_none() {
self.0 = Some(Default::default()); self.0 = Some(Default::default());
@ -89,13 +90,13 @@ impl Imports {
self.0.as_mut().unwrap().push((name.into(), module.into())); self.0.as_mut().unwrap().push((name.into(), module.into()));
} }
/// Truncate the stack of imported modules to a particular length. /// Truncate the stack of imported [modules][Module] to a particular length.
pub fn truncate(&mut self, size: usize) { pub fn truncate(&mut self, size: usize) {
if self.0.is_some() { if self.0.is_some() {
self.0.as_mut().unwrap().truncate(size); self.0.as_mut().unwrap().truncate(size);
} }
} }
/// Get an iterator to this stack of imported modules in reverse order. /// Get an iterator to this stack of imported [modules][Module] in reverse order.
#[allow(dead_code)] #[allow(dead_code)]
pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a { pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a {
self.0.iter().flat_map(|lib| { self.0.iter().flat_map(|lib| {
@ -104,22 +105,22 @@ impl Imports {
.map(|(name, module)| (name.clone(), module.clone())) .map(|(name, module)| (name.clone(), module.clone()))
}) })
} }
/// Get an iterator to this stack of imported modules in reverse order. /// Get an iterator to this stack of imported [modules][Module] in reverse order.
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn iter_raw<'a>( pub(crate) fn iter_raw<'a>(
&'a self, &'a self,
) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a { ) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> + 'a {
self.0.iter().flat_map(|lib| lib.iter().rev().cloned()) self.0.iter().flat_map(|lib| lib.iter().rev().cloned())
} }
/// Get a consuming iterator to this stack of imported modules in reverse order. /// Get a consuming iterator to this stack of imported [modules][Module] in reverse order.
pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> { pub fn into_iter(self) -> impl Iterator<Item = (ImmutableString, Shared<Module>)> {
self.0.into_iter().flat_map(|lib| lib.into_iter().rev()) self.0.into_iter().flat_map(|lib| lib.into_iter().rev())
} }
/// Add a stream of imported modules. /// Add a stream of imported [modules][Module].
pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) { pub fn extend(&mut self, stream: impl Iterator<Item = (ImmutableString, Shared<Module>)>) {
self.0.as_mut().unwrap().extend(stream) self.0.as_mut().unwrap().extend(stream)
} }
/// Does the specified function hash key exist in this stack of imported modules? /// Does the specified function hash key exist in this stack of imported [modules][Module]?
#[allow(dead_code)] #[allow(dead_code)]
pub fn contains_fn(&self, hash: u64) -> bool { pub fn contains_fn(&self, hash: u64) -> bool {
self.0.as_ref().map_or(false, |x| { self.0.as_ref().map_or(false, |x| {
@ -132,14 +133,14 @@ impl Imports {
.as_ref() .as_ref()
.and_then(|x| x.iter().rev().find_map(|(_, m)| m.get_qualified_fn(hash))) .and_then(|x| x.iter().rev().find_map(|(_, m)| m.get_qualified_fn(hash)))
} }
/// Does the specified TypeId iterator exist in this stack of imported modules? /// Does the specified [`TypeId`][std::any::TypeId] iterator exist in this stack of imported [modules][Module]?
#[allow(dead_code)] #[allow(dead_code)]
pub fn contains_iter(&self, id: TypeId) -> bool { pub fn contains_iter(&self, id: TypeId) -> bool {
self.0.as_ref().map_or(false, |x| { self.0.as_ref().map_or(false, |x| {
x.iter().any(|(_, m)| m.contains_qualified_iter(id)) x.iter().any(|(_, m)| m.contains_qualified_iter(id))
}) })
} }
/// Get the specified TypeId iterator. /// Get the specified [`TypeId`][std::any::TypeId] iterator.
pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> { pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
self.0 self.0
.as_ref() .as_ref()
@ -462,7 +463,7 @@ impl<T: Into<Dynamic>> From<T> for Target<'_> {
} }
} }
/// _(INTERNALS)_ A type that holds all the current states of the Engine. /// _(INTERNALS)_ A type that holds all the current states of the [`Engine`].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// ## WARNING /// ## WARNING
@ -512,17 +513,17 @@ pub struct Limits {
pub max_function_expr_depth: usize, pub max_function_expr_depth: usize,
/// Maximum number of operations allowed to run (0 = unlimited). /// Maximum number of operations allowed to run (0 = unlimited).
pub max_operations: u64, pub max_operations: u64,
/// Maximum number of modules allowed to load. /// Maximum number of [modules][Module] allowed to load.
/// Not available under `no_module`. /// Not available under `no_module`.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
pub max_modules: usize, pub max_modules: usize,
/// Maximum length of a string (0 = unlimited). /// Maximum length of a [string][ImmutableString] (0 = unlimited).
pub max_string_size: usize, pub max_string_size: usize,
/// Maximum length of an array (0 = unlimited). /// Maximum length of an [array][Array] (0 = unlimited).
/// Not available under `no_index`. /// Not available under `no_index`.
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub max_array_size: usize, pub max_array_size: usize,
/// Maximum number of properties in a map (0 = unlimited). /// Maximum number of properties in an [object map][Map] (0 = unlimited).
/// Not available under `no_object`. /// Not available under `no_object`.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
pub max_map_size: usize, pub max_map_size: usize,
@ -578,7 +579,7 @@ impl<'e, 'x, 'px, 'a, 's, 'm, 'pm, 't, 'pt> EvalContext<'e, 'x, 'px, 'a, 's, 'm,
/// [`Engine`] is re-entrant. /// [`Engine`] is re-entrant.
/// ///
/// Currently, [`Engine`] is neither [`Send`] nor [`Sync`]. /// Currently, [`Engine`] is neither [`Send`] nor [`Sync`].
/// Use the [`Sync`] feature to make it [`Send`] `+` [`Sync`]. /// Use the `sync` feature to make it [`Send`] `+` [`Sync`].
/// ///
/// # Example /// # Example
/// ///

View File

@ -37,10 +37,10 @@ impl Engine {
/// ///
/// ## WARNING - Low Level API /// ## WARNING - Low Level API
/// ///
/// This function is very low level. It takes a list of [`TypeId`]'s indicating the actual types of the parameters. /// This function is very low level. It takes a list of [`TypeId`][std::any::TypeId]'s indicating the actual types of the parameters.
/// ///
/// Arguments are simply passed in as a mutable array of [`&mut Dynamic`][Dynamic], /// Arguments are simply passed in as a mutable array of [`&mut Dynamic`][Dynamic],
/// The arguments are guaranteed to be of the correct types matching the [`TypeId`]'s. /// The arguments are guaranteed to be of the correct types matching the [`TypeId`][std::any::TypeId]'s.
/// ///
/// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::<T>()` /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::<T>()`
/// ///
@ -1639,7 +1639,7 @@ impl Engine {
.lib() .lib()
.iter_fn() .iter_fn()
.filter(|f| f.func.is_script()) .filter(|f| f.func.is_script())
.map(|f| (**f.func.get_fn_def()).clone()) .map(|f| f.func.get_fn_def().clone())
.collect(); .collect();
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]

View File

@ -72,7 +72,7 @@ impl Engine {
pub fn max_operations(&self) -> u64 { pub fn max_operations(&self) -> u64 {
self.limits.max_operations self.limits.max_operations
} }
/// Set the maximum number of imported modules allowed for a script. /// Set the maximum number of imported [modules][crate::Module] allowed for a script.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
@ -80,7 +80,7 @@ impl Engine {
self.limits.max_modules = modules; self.limits.max_modules = modules;
self self
} }
/// The maximum number of imported modules allowed for a script. /// The maximum number of imported [modules][crate::Module] allowed for a script.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline(always)] #[inline(always)]
@ -123,20 +123,20 @@ impl Engine {
pub fn max_function_expr_depth(&self) -> usize { pub fn max_function_expr_depth(&self) -> usize {
self.limits.max_function_expr_depth self.limits.max_function_expr_depth
} }
/// Set the maximum length of strings (0 for unlimited). /// Set the maximum length of [strings][crate::ImmutableString] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self { pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
self.limits.max_string_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_string_size = if max_size == usize::MAX { 0 } else { max_size };
self self
} }
/// The maximum length of strings (0 for unlimited). /// The maximum length of [strings][crate::ImmutableString] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[inline(always)] #[inline(always)]
pub fn max_string_size(&self) -> usize { pub fn max_string_size(&self) -> usize {
self.limits.max_string_size self.limits.max_string_size
} }
/// Set the maximum length of arrays (0 for unlimited). /// Set the maximum length of [arrays][crate::Array] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)] #[inline(always)]
@ -144,14 +144,14 @@ impl Engine {
self.limits.max_array_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_array_size = if max_size == usize::MAX { 0 } else { max_size };
self self
} }
/// The maximum length of arrays (0 for unlimited). /// The maximum length of [arrays][crate::Array] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[inline(always)] #[inline(always)]
pub fn max_array_size(&self) -> usize { pub fn max_array_size(&self) -> usize {
self.limits.max_array_size self.limits.max_array_size
} }
/// Set the maximum length of object maps (0 for unlimited). /// Set the maximum length of [object maps][crate::Map] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]
@ -159,7 +159,7 @@ impl Engine {
self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size }; self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
self self
} }
/// The maximum length of object maps (0 for unlimited). /// The maximum length of [object maps][crate::Map] (0 for unlimited).
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline(always)] #[inline(always)]

View File

@ -6,7 +6,7 @@ use crate::dynamic::Variant;
use crate::{Dynamic, StaticVec}; use crate::{Dynamic, StaticVec};
/// Trait that represents arguments to a function call. /// Trait that represents arguments to a function call.
/// Any data type that can be converted into a `Vec<Dynamic>` can be used /// Any data type that can be converted into a [`Vec`]`<`[`Dynamic`]`>` can be used
/// as arguments to a function call. /// as arguments to a function call.
pub trait FuncArgs { pub trait FuncArgs {
/// Convert to a [`StaticVec`]`<`[`Dynamic`]`>` of the function call arguments. /// Convert to a [`StaticVec`]`<`[`Dynamic`]`>` of the function call arguments.

View File

@ -1166,7 +1166,7 @@ impl Engine {
} }
} }
f.get_native_fn().clone()((self, &*mods, lib).into(), args.as_mut()) f.get_native_fn()((self, &*mods, lib).into(), args.as_mut())
} }
Some(_) => unreachable!(), Some(_) => unreachable!(),
None if def_val.is_some() => Ok(def_val.unwrap().clone()), None if def_val.is_some() => Ok(def_val.unwrap().clone()),

View File

@ -37,15 +37,15 @@ pub type Shared<T> = Rc<T>;
pub type Shared<T> = Arc<T>; pub type Shared<T> = Arc<T>;
/// Synchronized shared object. /// Synchronized shared object.
#[cfg(any(not(feature = "no_closure"), not(feature = "no_module")))] #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type Locked<T> = crate::stdlib::cell::RefCell<T>; pub type Locked<T> = crate::stdlib::cell::RefCell<T>;
/// Synchronized shared object. /// Synchronized shared object.
#[cfg(any(not(feature = "no_closure"), not(feature = "no_module")))] #[cfg(not(feature = "no_closure"))]
#[cfg(feature = "sync")] #[cfg(feature = "sync")]
pub type Locked<T> = crate::stdlib::sync::RwLock<T>; pub type Locked<T> = crate::stdlib::sync::RwLock<T>;
/// Context of native Rust function call. /// Context of a native Rust function call.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct NativeCallContext<'e, 'a, 'm, 'pm: 'm> { pub struct NativeCallContext<'e, 'a, 'm, 'pm: 'm> {
engine: &'e Engine, engine: &'e Engine,
@ -207,6 +207,7 @@ pub fn shared_take<T>(value: Shared<T>) -> T {
shared_try_take(value).map_err(|_| ()).unwrap() shared_try_take(value).map_err(|_| ()).unwrap()
} }
/// Arguments to a function call, which is a list of [`&mut Dynamic`][Dynamic].
pub type FnCallArgs<'a> = [&'a mut Dynamic]; pub type FnCallArgs<'a> = [&'a mut Dynamic];
/// A general function pointer, which may carry additional (i.e. curried) argument values /// A general function pointer, which may carry additional (i.e. curried) argument values
@ -488,9 +489,9 @@ impl CallableFunction {
/// ///
/// Panics if the [`CallableFunction`] is not [`Pure`][CallableFunction::Pure] or /// Panics if the [`CallableFunction`] is not [`Pure`][CallableFunction::Pure] or
/// [`Method`][CallableFunction::Method]. /// [`Method`][CallableFunction::Method].
pub fn get_native_fn(&self) -> &Shared<FnAny> { pub fn get_native_fn(&self) -> &FnAny {
match self { match self {
Self::Pure(f) | Self::Method(f) => f, Self::Pure(f) | Self::Method(f) => f.as_ref(),
Self::Iterator(_) | Self::Plugin(_) => unreachable!(), Self::Iterator(_) | Self::Plugin(_) => unreachable!(),
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
@ -503,10 +504,10 @@ impl CallableFunction {
/// ///
/// Panics if the [`CallableFunction`] is not [`Script`][CallableFunction::Script]. /// Panics if the [`CallableFunction`] is not [`Script`][CallableFunction::Script].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub fn get_fn_def(&self) -> &Shared<ScriptFnDef> { pub fn get_fn_def(&self) -> &ScriptFnDef {
match self { match self {
Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => unreachable!(), Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => unreachable!(),
Self::Script(f) => f, Self::Script(f) => f.as_ref(),
} }
} }
/// Get a reference to an iterator function. /// Get a reference to an iterator function.
@ -528,9 +529,9 @@ impl CallableFunction {
/// # Panics /// # Panics
/// ///
/// Panics if the [`CallableFunction`] is not [`Plugin`][CallableFunction::Plugin]. /// Panics if the [`CallableFunction`] is not [`Plugin`][CallableFunction::Plugin].
pub fn get_plugin_fn<'s>(&'s self) -> &Shared<FnPlugin> { pub fn get_plugin_fn<'s>(&'s self) -> &FnPlugin {
match self { match self {
Self::Plugin(f) => f, Self::Plugin(f) => f.as_ref(),
Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => unreachable!(), Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => unreachable!(),
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]

View File

@ -10,9 +10,9 @@ use crate::{
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, NativeCallContext, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, NativeCallContext,
}; };
/// Trait to register custom functions with the `Engine`. /// Trait to register custom functions with the [`Engine`].
pub trait RegisterFn<FN, ARGS, RET> { pub trait RegisterFn<FN, ARGS, RET> {
/// Register a custom function with the `Engine`. /// Register a custom function with the [`Engine`].
/// ///
/// # Example /// # Example
/// ///
@ -42,9 +42,9 @@ pub trait RegisterFn<FN, ARGS, RET> {
fn register_fn(&mut self, name: &str, f: FN) -> &mut Self; fn register_fn(&mut self, name: &str, f: FN) -> &mut Self;
} }
/// Trait to register fallible custom functions returning `Result<Dynamic, Box<EvalAltResult>>` with the `Engine`. /// Trait to register fallible custom functions returning [`Result`]`<`[`Dynamic`]`, `[`Box`]`<`[`EvalAltResult`]`>>` with the [`Engine`].
pub trait RegisterResultFn<FN, ARGS> { pub trait RegisterResultFn<FN, ARGS> {
/// Register a custom fallible function with the `Engine`. /// Register a custom fallible function with the [`Engine`].
/// ///
/// # Example /// # Example
/// ///
@ -75,7 +75,7 @@ pub trait RegisterResultFn<FN, ARGS> {
// 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.
// That is because stable Rust currently does not allow distinguishing implementations // That is because stable Rust currently does not allow distinguishing implementations
// based purely on parameter types of traits (Fn, FnOnce and FnMut). // based purely on parameter types of traits (`Fn`, `FnOnce` and `FnMut`).
// //
// For example: // For example:
// //

View File

@ -83,20 +83,22 @@ mod token;
mod r#unsafe; mod r#unsafe;
mod utils; mod utils;
/// The system integer type. It is defined as `i64`. /// The system integer type. It is defined as [`i64`].
/// ///
/// If the `only_i32` feature is enabled, this will be `i32` instead. /// If the `only_i32` feature is enabled, this will be [`i32`] instead.
#[cfg(not(feature = "only_i32"))] #[cfg(not(feature = "only_i32"))]
pub type INT = i64; pub type INT = i64;
/// The system integer type. /// The system integer type.
/// It is defined as `i32` since the `only_i32` feature is used. /// It is defined as [`i32`] since the `only_i32` feature is used.
/// ///
/// If the `only_i32` feature is not enabled, this will be `i64` instead. /// If the `only_i32` feature is not used, this will be `i64` instead.
#[cfg(feature = "only_i32")] #[cfg(feature = "only_i32")]
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`].
///
/// If the `f32_float` feature is enabled, this will be [`i32`] instead.
/// ///
/// Not available under the `no_float` feature. /// Not available under the `no_float` feature.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -104,7 +106,9 @@ pub type INT = i32;
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.
///
/// If the `f32_float` feature is not used, this will be `f64` instead.
/// ///
/// Not available under the `no_float` feature. /// Not available under the `no_float` feature.
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -114,7 +118,7 @@ pub type FLOAT = f32;
pub use ast::{FnAccess, AST}; pub use ast::{FnAccess, AST};
pub use dynamic::Dynamic; pub use dynamic::Dynamic;
pub use engine::{Engine, EvalContext}; pub use engine::{Engine, EvalContext};
pub use fn_native::{FnPtr, NativeCallContext}; pub use fn_native::{FnPtr, NativeCallContext, Shared};
pub use fn_register::{RegisterFn, RegisterResultFn}; pub use fn_register::{RegisterFn, RegisterResultFn};
pub use module::{FnNamespace, Module}; pub use module::{FnNamespace, Module};
pub use parse_error::{LexError, ParseError, ParseErrorType}; pub use parse_error::{LexError, ParseError, ParseErrorType};
@ -124,8 +128,8 @@ pub use syntax::Expression;
pub use token::Position; pub use token::Position;
pub use utils::ImmutableString; pub use utils::ImmutableString;
#[allow(dead_code)] #[cfg(not(feature = "no_closure"))]
use fn_native::{Locked, Shared}; use fn_native::Locked;
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
pub use utils::{calc_native_fn_hash, calc_script_fn_hash}; pub use utils::{calc_native_fn_hash, calc_script_fn_hash};
@ -138,13 +142,13 @@ pub use rhai_codegen::*;
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub use fn_func::Func; pub use fn_func::Func;
/// Variable-sized array of `Dynamic` values. /// Variable-sized array of [`Dynamic`] values.
/// ///
/// Not available under the `no_index` feature. /// Not available under the `no_index` feature.
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub type Array = stdlib::vec::Vec<Dynamic>; pub type Array = stdlib::vec::Vec<Dynamic>;
/// Hash map of `Dynamic` values with `ImmutableString` keys. /// Hash map of [`Dynamic`] values with [`ImmutableString`] keys.
/// ///
/// Not available under the `no_object` feature. /// Not available under the `no_object` feature.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
@ -181,20 +185,24 @@ pub use ast::{
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated(note = "this type is volatile and may change")] #[deprecated(note = "this type is volatile and may change")]
pub use engine::{Imports, Limits, State as EvalState}; pub use engine::{Imports, State as EvalState};
#[cfg(feature = "internals")]
#[cfg(not(feature = "unchecked"))]
pub use engine::Limits;
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[deprecated(note = "this type is volatile and may change")] #[deprecated(note = "this type is volatile and may change")]
pub use module::NamespaceRef; pub use module::NamespaceRef;
/// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec), /// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored. /// which is a specialized [`Vec`] backed by a small, fixed-size array when there are <= 4 items stored.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(not(feature = "internals"))] #[cfg(not(feature = "internals"))]
type StaticVec<T> = smallvec::SmallVec<[T; 4]>; type StaticVec<T> = smallvec::SmallVec<[T; 4]>;
/// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec), /// _(INTERNALS)_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored. /// which is a specialized [`Vec`] backed by a small, fixed-size array when there are <= 4 items stored.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
pub type StaticVec<T> = smallvec::SmallVec<[T; 4]>; pub type StaticVec<T> = smallvec::SmallVec<[T; 4]>;

View File

@ -9,7 +9,7 @@ use crate::stdlib::{
boxed::Box, boxed::Box,
collections::HashMap, collections::HashMap,
fmt, format, fmt, format,
iter::{empty, once}, iter::empty,
num::NonZeroUsize, num::NonZeroUsize,
ops::{Add, AddAssign, Deref, DerefMut}, ops::{Add, AddAssign, Deref, DerefMut},
string::{String, ToString}, string::{String, ToString},
@ -21,6 +21,9 @@ use crate::{
Dynamic, EvalAltResult, ImmutableString, NativeCallContext, Position, Shared, StaticVec, Dynamic, EvalAltResult, ImmutableString, NativeCallContext, Position, Shared, StaticVec,
}; };
#[cfg(not(feature = "no_function"))]
use crate::ast::ScriptFnDef;
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
use crate::Array; use crate::Array;
@ -28,9 +31,6 @@ use crate::Array;
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::Map; use crate::Map;
#[cfg(not(feature = "no_function"))]
pub type SharedScriptFnDef = Shared<crate::ast::ScriptFnDef>;
/// A type representing the namespace of a function. /// A type representing the namespace of a function.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum FnNamespace { pub enum FnNamespace {
@ -47,7 +47,7 @@ impl Default for FnNamespace {
} }
impl FnNamespace { impl FnNamespace {
/// Is this namespace global? /// Is this namespace [global][FnNamespace::Global]?
#[inline(always)] #[inline(always)]
pub fn is_global(self) -> bool { pub fn is_global(self) -> bool {
match self { match self {
@ -55,7 +55,7 @@ impl FnNamespace {
Self::Internal => false, Self::Internal => false,
} }
} }
/// Is this namespace internal? /// Is this namespace [internal][FnNamespace::Internal]?
#[inline(always)] #[inline(always)]
pub fn is_internal(self) -> bool { pub fn is_internal(self) -> bool {
match self { match self {
@ -357,10 +357,14 @@ impl Module {
/// If there is an existing function of the same name and number of arguments, it is replaced. /// If there is an existing function of the same name and number of arguments, it is replaced.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline] #[inline]
pub(crate) fn set_script_fn(&mut self, fn_def: SharedScriptFnDef) -> u64 { pub(crate) fn set_script_fn(&mut self, fn_def: impl Into<Shared<ScriptFnDef>>) -> u64 {
let fn_def = fn_def.into();
// None + function name + number of arguments. // None + function name + number of arguments.
let num_params = fn_def.params.len(); let num_params = fn_def.params.len();
let hash_script = crate::calc_script_fn_hash(empty(), &fn_def.name, num_params); let hash_script = crate::calc_script_fn_hash(empty(), &fn_def.name, num_params);
let mut param_names: StaticVec<_> = fn_def.params.iter().cloned().collect();
param_names.push("Dynamic".into());
self.functions.insert( self.functions.insert(
hash_script, hash_script,
FuncInfo { FuncInfo {
@ -369,14 +373,7 @@ impl Module {
access: fn_def.access, access: fn_def.access,
params: num_params, params: num_params,
param_types: None, param_types: None,
param_names: Some( param_names: Some(param_names),
fn_def
.params
.iter()
.cloned()
.chain(once("Dynamic".into()))
.collect(),
),
func: fn_def.into(), func: fn_def.into(),
}, },
); );
@ -392,7 +389,7 @@ impl Module {
name: &str, name: &str,
num_params: usize, num_params: usize,
public_only: bool, public_only: bool,
) -> Option<&SharedScriptFnDef> { ) -> Option<&ScriptFnDef> {
self.functions self.functions
.values() .values()
.find( .find(
@ -1527,12 +1524,12 @@ impl Module {
/// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]). /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]).
/// 3) Function name (as string slice). /// 3) Function name (as string slice).
/// 4) Number of parameters. /// 4) Number of parameters.
/// 5) Shared reference to function definition [`ScriptFnDef`][crate::ScriptFnDef]. /// 5) Shared reference to function definition [`ScriptFnDef`][crate::ast::ScriptFnDef].
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[inline(always)] #[inline(always)]
pub(crate) fn iter_script_fn<'a>( pub(crate) fn iter_script_fn<'a>(
&'a self, &'a self,
) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, SharedScriptFnDef)> + 'a { ) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, &ScriptFnDef)> + 'a {
self.functions.values().filter(|f| f.func.is_script()).map( self.functions.values().filter(|f| f.func.is_script()).map(
|FuncInfo { |FuncInfo {
namespace, namespace,
@ -1547,7 +1544,7 @@ impl Module {
*access, *access,
name.as_str(), name.as_str(),
*params, *params,
func.get_fn_def().clone(), func.get_fn_def(),
) )
}, },
) )
@ -1584,14 +1581,14 @@ impl Module {
/// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]). /// 2) Access mode ([`FnAccess::Public`] or [`FnAccess::Private`]).
/// 3) Function name (as string slice). /// 3) Function name (as string slice).
/// 4) Number of parameters. /// 4) Number of parameters.
/// 5) _(INTERNALS)_ Shared reference to function definition [`ScriptFnDef`][crate::ScriptFnDef]. /// 5) _(INTERNALS)_ Shared reference to function definition [`ScriptFnDef`][crate::ast::ScriptFnDef].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(feature = "internals")] #[cfg(feature = "internals")]
#[inline(always)] #[inline(always)]
pub fn iter_script_fn_info( pub fn iter_script_fn_info(
&self, &self,
) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, SharedScriptFnDef)> { ) -> impl Iterator<Item = (FnNamespace, FnAccess, &str, usize, &ScriptFnDef)> {
self.iter_script_fn() self.iter_script_fn()
} }
@ -1653,14 +1650,16 @@ impl Module {
// Non-private functions defined become module functions // Non-private functions defined become module functions
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
{ {
ast.iter_functions() ast.lib()
.filter(|(_, access, _, _, _)| !access.is_private()) .functions
.for_each(|(_, _, _, _, func)| { .values()
.filter(|FuncInfo { access, func, .. }| !access.is_private() && func.is_script())
.for_each(|FuncInfo { func, .. }| {
// Encapsulate AST environment // Encapsulate AST environment
let mut func = func.as_ref().clone(); let mut func = func.get_fn_def().clone();
func.lib = Some(ast.shared_lib()); func.lib = Some(ast.shared_lib());
func.mods = func_mods.clone(); func.mods = func_mods.clone();
module.set_script_fn(func.into()); module.set_script_fn(func);
}); });
} }
@ -1827,7 +1826,7 @@ impl Module {
} }
} }
/// _(INTERNALS)_ A chain of module names to namespace-qualify a variable or function call. /// _(INTERNALS)_ A chain of [module][Module] names to namespace-qualify a variable or function call.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// A [`u64`] hash key is cached for quick search purposes. /// A [`u64`] hash key is cached for quick search purposes.

View File

@ -1,7 +1,7 @@
use crate::stdlib::{ use crate::stdlib::{
boxed::Box, collections::HashMap, io::Error as IoError, path::PathBuf, string::String, boxed::Box, collections::HashMap, io::Error as IoError, path::PathBuf, string::String,
}; };
use crate::{Engine, EvalAltResult, Locked, Module, ModuleResolver, Position, Shared}; use crate::{Engine, EvalAltResult, Module, ModuleResolver, Position, Shared};
/// Module resolution service that loads module script files from the file system. /// Module resolution service that loads module script files from the file system.
/// ///
@ -37,7 +37,11 @@ use crate::{Engine, EvalAltResult, Locked, Module, ModuleResolver, Position, Sha
pub struct FileModuleResolver { pub struct FileModuleResolver {
path: PathBuf, path: PathBuf,
extension: String, extension: String,
cache: Locked<HashMap<PathBuf, Shared<Module>>>,
#[cfg(not(feature = "sync"))]
cache: crate::stdlib::cell::RefCell<HashMap<PathBuf, Shared<Module>>>,
#[cfg(feature = "sync")]
cache: crate::stdlib::sync::RwLock<HashMap<PathBuf, Shared<Module>>>,
} }
impl Default for FileModuleResolver { impl Default for FileModuleResolver {

View File

@ -1,4 +1,4 @@
//! Module implementing the AST optimizer. //! Module implementing the [`AST`] optimizer.
use crate::ast::{Expr, ScriptFnDef, Stmt}; use crate::ast::{Expr, ScriptFnDef, Stmt};
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF}; use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF};
@ -32,19 +32,20 @@ pub enum OptimizationLevel {
} }
impl OptimizationLevel { impl OptimizationLevel {
/// Is the `OptimizationLevel` None. /// Is the `OptimizationLevel` [`None`][OptimizationLevel::None]?
#[allow(dead_code)]
#[inline(always)] #[inline(always)]
pub fn is_none(self) -> bool { pub fn is_none(self) -> bool {
self == Self::None self == Self::None
} }
/// Is the `OptimizationLevel` Simple. /// Is the `OptimizationLevel` [`Simple`][OptimizationLevel::Simple]?
#[cfg(not(feature = "no_optimize"))] #[allow(dead_code)]
#[inline(always)] #[inline(always)]
pub fn is_simple(self) -> bool { pub fn is_simple(self) -> bool {
self == Self::Simple self == Self::Simple
} }
/// Is the `OptimizationLevel` Full. /// Is the `OptimizationLevel` [`Full`][OptimizationLevel::Full]?
#[cfg(not(feature = "no_optimize"))] #[allow(dead_code)]
#[inline(always)] #[inline(always)]
pub fn is_full(self) -> bool { pub fn is_full(self) -> bool {
self == Self::Full self == Self::Full
@ -54,13 +55,13 @@ impl OptimizationLevel {
/// Mutable state throughout an optimization pass. /// Mutable state throughout an optimization pass.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct State<'a> { struct State<'a> {
/// Has the AST been changed during this pass? /// Has the [`AST`] been changed during this pass?
changed: bool, changed: bool,
/// Collection of constants to use for eager function evaluations. /// Collection of constants to use for eager function evaluations.
constants: Vec<(String, Expr)>, constants: Vec<(String, Expr)>,
/// An `Engine` instance for eager function evaluation. /// An [`Engine`] instance for eager function evaluation.
engine: &'a Engine, engine: &'a Engine,
/// Library of script-defined functions. /// [Module] containing script-defined functions.
lib: &'a [&'a Module], lib: &'a [&'a Module],
/// Optimization level. /// Optimization level.
optimization_level: OptimizationLevel, optimization_level: OptimizationLevel,
@ -83,12 +84,12 @@ impl<'a> State<'a> {
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.changed = false; self.changed = false;
} }
/// Set the AST state to be dirty (i.e. changed). /// Set the [`AST`] state to be dirty (i.e. changed).
#[inline(always)] #[inline(always)]
pub fn set_dirty(&mut self) { pub fn set_dirty(&mut self) {
self.changed = true; self.changed = true;
} }
/// Is the AST dirty (i.e. changed)? /// Is the [`AST`] dirty (i.e. changed)?
#[inline(always)] #[inline(always)]
pub fn is_dirty(&self) -> bool { pub fn is_dirty(&self) -> bool {
self.changed self.changed
@ -147,7 +148,7 @@ fn call_fn_with_constant_arguments(
.map(|(v, _)| v) .map(|(v, _)| v)
} }
/// Optimize a block of statements. /// Optimize a block of [statements][crate::ast::Stmt].
fn optimize_stmt_block( fn optimize_stmt_block(
mut statements: Vec<Stmt>, mut statements: Vec<Stmt>,
pos: Position, pos: Position,
@ -264,7 +265,7 @@ fn optimize_stmt_block(
} }
} }
/// Optimize a statement. /// Optimize a [statement][crate::ast::Stmt].
fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) { fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
match stmt { match stmt {
// expr op= expr // expr op= expr
@ -460,7 +461,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
} }
} }
/// Optimize an expression. /// Optimize an [expression][crate::ast::Expr].
fn optimize_expr(expr: &mut Expr, state: &mut State) { fn optimize_expr(expr: &mut Expr, state: &mut State) {
// These keywords are handled specially // These keywords are handled specially
const DONT_EVAL_KEYWORDS: &[&str] = &[ const DONT_EVAL_KEYWORDS: &[&str] = &[
@ -724,7 +725,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
} }
} }
fn optimize( /// Optimize a block of [statements][crate::ast::Stmt] at top level.
fn optimize_top_level(
mut statements: Vec<Stmt>, mut statements: Vec<Stmt>,
engine: &Engine, engine: &Engine,
scope: &Scope, scope: &Scope,
@ -815,7 +817,7 @@ fn optimize(
statements statements
} }
/// Optimize an AST. /// Optimize an [`AST`].
pub fn optimize_into_ast( pub fn optimize_into_ast(
engine: &Engine, engine: &Engine,
scope: &Scope, scope: &Scope,
@ -839,19 +841,16 @@ pub fn optimize_into_ast(
_functions _functions
.iter() .iter()
.map(|fn_def| { .map(|fn_def| ScriptFnDef {
ScriptFnDef { name: fn_def.name.clone(),
name: fn_def.name.clone(), access: fn_def.access,
access: fn_def.access, body: Default::default(),
body: Default::default(), params: fn_def.params.clone(),
params: fn_def.params.clone(), #[cfg(not(feature = "no_closure"))]
#[cfg(not(feature = "no_closure"))] externals: fn_def.externals.clone(),
externals: fn_def.externals.clone(), lib: None,
lib: None, #[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_module"))] mods: Default::default(),
mods: Default::default(),
}
.into()
}) })
.for_each(|fn_def| { .for_each(|fn_def| {
lib2.set_script_fn(fn_def); lib2.set_script_fn(fn_def);
@ -863,8 +862,13 @@ pub fn optimize_into_ast(
let pos = fn_def.body.position(); let pos = fn_def.body.position();
// Optimize the function body // Optimize the function body
let mut body = let mut body = optimize_top_level(
optimize(vec![fn_def.body], engine, &Scope::new(), &[&lib2], level); vec![fn_def.body],
engine,
&Scope::new(),
&[&lib2],
level,
);
// {} -> Noop // {} -> Noop
fn_def.body = match body.pop().unwrap_or_else(|| Stmt::Noop(pos)) { fn_def.body = match body.pop().unwrap_or_else(|| Stmt::Noop(pos)) {
@ -879,14 +883,14 @@ pub fn optimize_into_ast(
// All others // All others
stmt => stmt, stmt => stmt,
}; };
fn_def.into() fn_def
}) })
.for_each(|fn_def| { .for_each(|fn_def| {
module.set_script_fn(fn_def); module.set_script_fn(fn_def);
}); });
} else { } else {
_functions.into_iter().for_each(|fn_def| { _functions.into_iter().for_each(|fn_def| {
module.set_script_fn(fn_def.into()); module.set_script_fn(fn_def);
}); });
} }
@ -902,7 +906,7 @@ pub fn optimize_into_ast(
match level { match level {
OptimizationLevel::None => statements, OptimizationLevel::None => statements,
OptimizationLevel::Simple | OptimizationLevel::Full => { OptimizationLevel::Simple | OptimizationLevel::Full => {
optimize(statements, engine, &scope, &[&lib], level) optimize_top_level(statements, engine, &scope, &[&lib], level)
} }
}, },
lib, lib,

View File

@ -1,11 +1,10 @@
use crate::plugin::*; use crate::plugin::*;
use crate::stdlib::iter::empty; use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
use crate::{calc_script_fn_hash, def_package, FnPtr, ImmutableString, NativeCallContext, INT};
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
use crate::{module::SharedScriptFnDef, stdlib::collections::HashMap, Array, Map}; use crate::{ast::ScriptFnDef, stdlib::collections::HashMap, Array, Map};
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);
@ -20,6 +19,8 @@ mod fn_ptr_functions {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub mod functions { pub mod functions {
use crate::{calc_script_fn_hash, stdlib::iter::empty, INT};
#[rhai_fn(name = "is_anonymous", get = "is_anonymous")] #[rhai_fn(name = "is_anonymous", get = "is_anonymous")]
pub fn is_anonymous(f: &mut FnPtr) -> bool { pub fn is_anonymous(f: &mut FnPtr) -> bool {
f.is_anonymous() f.is_anonymous()
@ -54,7 +55,7 @@ fn collect_fn_metadata(ctx: NativeCallContext) -> Array {
fn make_metadata( fn make_metadata(
dict: &HashMap<&str, ImmutableString>, dict: &HashMap<&str, ImmutableString>,
namespace: Option<ImmutableString>, namespace: Option<ImmutableString>,
f: SharedScriptFnDef, f: &ScriptFnDef,
) -> Map { ) -> Map {
let mut map = Map::with_capacity(6); let mut map = Map::with_capacity(6);

View File

@ -26,7 +26,7 @@ where
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<T> {
if self.0 < self.1 { if self.0 < self.1 {
let v = self.0.clone(); let v = self.0.clone();
self.0 = &v + &self.2; self.0 = self.0.add(&self.2);
Some(v) Some(v)
} else { } else {
None None

View File

@ -68,10 +68,10 @@ impl LexError {
Self::ImproperSymbol(_, _) => "Invalid symbol encountered", Self::ImproperSymbol(_, _) => "Invalid symbol encountered",
} }
} }
/// Convert a `&LexError` into a [`ParseError`]. /// Convert a [`LexError`] into a [`ParseError`].
#[inline(always)] #[inline(always)]
pub fn into_err(&self, pos: Position) -> ParseError { pub fn into_err(self, pos: Position) -> ParseError {
ParseError(Box::new(self.clone().into()), pos) ParseError(Box::new(self.into()), pos)
} }
} }

View File

@ -25,20 +25,24 @@ use crate::syntax::CustomSyntax;
use crate::token::{is_keyword_function, is_valid_identifier, Token, TokenStream}; use crate::token::{is_keyword_function, is_valid_identifier, Token, TokenStream};
use crate::utils::{get_hasher, StraightHasherBuilder}; use crate::utils::{get_hasher, StraightHasherBuilder};
use crate::{ use crate::{
calc_script_fn_hash, Dynamic, Engine, FnAccess, ImmutableString, LexError, ParseError, calc_script_fn_hash, Dynamic, Engine, ImmutableString, LexError, ParseError, ParseErrorType,
ParseErrorType, Position, Scope, StaticVec, AST, Position, Scope, StaticVec, AST,
}; };
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
use crate::FLOAT; use crate::FLOAT;
#[cfg(not(feature = "no_function"))]
use crate::FnAccess;
type PERR = ParseErrorType; type PERR = ParseErrorType;
type FunctionsLib = HashMap<u64, ScriptFnDef, StraightHasherBuilder>; type FunctionsLib = HashMap<u64, ScriptFnDef, StraightHasherBuilder>;
/// A type that encapsulates the current state of the parser.
#[derive(Debug)] #[derive(Debug)]
struct ParseState<'e> { struct ParseState<'e> {
/// Reference to the scripting `Engine`. /// Reference to the scripting [`Engine`].
engine: &'e Engine, engine: &'e Engine,
/// Hash that uniquely identifies a script. /// Hash that uniquely identifies a script.
script_hash: u64, script_hash: u64,
@ -57,7 +61,7 @@ struct ParseState<'e> {
/// All consequent calls to `access_var` will not be affected /// All consequent calls to `access_var` will not be affected
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
allow_capture: bool, allow_capture: bool,
/// Encapsulates a local stack with imported module names. /// Encapsulates a local stack with imported [module][crate::Module] names.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
modules: StaticVec<ImmutableString>, modules: StaticVec<ImmutableString>,
/// Maximum levels of expression nesting. /// Maximum levels of expression nesting.
@ -70,7 +74,7 @@ struct ParseState<'e> {
} }
impl<'e> ParseState<'e> { impl<'e> ParseState<'e> {
/// Create a new `ParseState`. /// Create a new [`ParseState`].
#[inline(always)] #[inline(always)]
pub fn new( pub fn new(
engine: &'e Engine, engine: &'e Engine,
@ -100,12 +104,12 @@ impl<'e> ParseState<'e> {
} }
} }
/// Find explicitly declared variable by name in the `ParseState`, searching in reverse order. /// Find explicitly declared variable by name in the [`ParseState`], searching in reverse order.
/// ///
/// If the variable is not present in the scope adds it to the list of external variables /// If the variable is not present in the scope adds it to the list of external variables
/// ///
/// The return value is the offset to be deducted from `Stack::len`, /// The return value is the offset to be deducted from `Stack::len`,
/// i.e. the top element of the `ParseState` is offset 1. /// i.e. the top element of the [`ParseState`] is offset 1.
/// ///
/// Return `None` when the variable name is not found in the `stack`. /// Return `None` when the variable name is not found in the `stack`.
#[inline] #[inline]
@ -144,12 +148,12 @@ impl<'e> ParseState<'e> {
} }
} }
/// Find a module by name in the `ParseState`, searching in reverse. /// Find a module by name in the [`ParseState`], searching in reverse.
/// ///
/// Returns the offset to be deducted from `Stack::len`, /// Returns the offset to be deducted from `Stack::len`,
/// i.e. the top element of the `ParseState` is offset 1. /// i.e. the top element of the [`ParseState`] is offset 1.
/// ///
/// Returns `None` when the variable name is not found in the `ParseState`. /// Returns `None` when the variable name is not found in the [`ParseState`].
/// ///
/// # Panics /// # Panics
/// ///
@ -183,8 +187,8 @@ impl<'e> ParseState<'e> {
} }
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
/// A type that encapsulates all the settings for a particular parsing function. /// A type that encapsulates all the settings for a particular parsing function.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
struct ParseSettings { struct ParseSettings {
/// Current position. /// Current position.
pos: Position, pos: Position,
@ -230,7 +234,8 @@ impl ParseSettings {
} }
impl Expr { impl Expr {
/// Convert a `Variable` into a `Property`. All other variants are untouched. /// Convert a [`Variable`][Expr::Variable] into a [`Property`][Expr::Property].
/// All other variants are untouched.
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
#[inline] #[inline]
fn into_property(self, state: &mut ParseState) -> Self { fn into_property(self, state: &mut ParseState) -> Self {
@ -246,7 +251,7 @@ impl Expr {
} }
} }
/// Consume a particular token, checking that it is the expected one. /// Consume a particular [token][Token], checking that it is the expected one.
fn eat_token(input: &mut TokenStream, token: Token) -> Position { fn eat_token(input: &mut TokenStream, token: Token) -> Position {
let (t, pos) = input.next().unwrap(); let (t, pos) = input.next().unwrap();
@ -261,7 +266,7 @@ fn eat_token(input: &mut TokenStream, token: Token) -> Position {
pos pos
} }
/// Match a particular token, consuming it if matched. /// Match a particular [token][Token], consuming it if matched.
fn match_token(input: &mut TokenStream, token: Token) -> (bool, Position) { fn match_token(input: &mut TokenStream, token: Token) -> (bool, Position) {
let (t, pos) = input.peek().unwrap(); let (t, pos) = input.peek().unwrap();
if *t == token { if *t == token {
@ -328,7 +333,7 @@ fn parse_fn_call(
.into_err(*token_pos)) .into_err(*token_pos))
} }
// id( <error> // id( <error>
Token::LexError(err) => return Err(err.into_err(*token_pos)), Token::LexError(err) => return Err(err.clone().into_err(*token_pos)),
// id() // id()
Token::RightParen => { Token::RightParen => {
eat_token(input, Token::RightParen); eat_token(input, Token::RightParen);
@ -422,7 +427,7 @@ fn parse_fn_call(
.into_err(*pos)) .into_err(*pos))
} }
// id(...args <error> // id(...args <error>
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
// id(...args ??? // id(...args ???
(_, pos) => { (_, pos) => {
return Err(PERR::MissingToken( return Err(PERR::MissingToken(
@ -610,7 +615,7 @@ fn parse_index_chain(
} }
} }
} }
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
(_, pos) => Err(PERR::MissingToken( (_, pos) => Err(PERR::MissingToken(
Token::RightBracket.into(), Token::RightBracket.into(),
"for a matching [ in this index expression".into(), "for a matching [ in this index expression".into(),
@ -672,7 +677,7 @@ fn parse_array_literal(
.into_err(*pos), .into_err(*pos),
) )
} }
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
(_, pos) => { (_, pos) => {
return Err(PERR::MissingToken( return Err(PERR::MissingToken(
Token::Comma.into(), Token::Comma.into(),
@ -781,7 +786,7 @@ fn parse_map_literal(
) )
.into_err(*pos)) .into_err(*pos))
} }
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
(_, pos) => { (_, pos) => {
return Err( return Err(
PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into()) PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into())
@ -899,7 +904,7 @@ fn parse_switch(
.into_err(*pos), .into_err(*pos),
) )
} }
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
(_, pos) if need_comma => { (_, pos) if need_comma => {
return Err(PERR::MissingToken( return Err(PERR::MissingToken(
Token::Comma.into(), Token::Comma.into(),
@ -2342,7 +2347,7 @@ fn parse_block(
// { ... { stmt } ??? // { ... { stmt } ???
(_, _) if !need_semicolon => (), (_, _) if !need_semicolon => (),
// { ... stmt <error> // { ... stmt <error>
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
// { ... stmt ??? // { ... stmt ???
(_, pos) => { (_, pos) => {
// Semicolons are not optional between statements // Semicolons are not optional between statements
@ -2960,7 +2965,7 @@ impl Engine {
// { stmt } ??? // { stmt } ???
(_, _) if !need_semicolon => (), (_, _) if !need_semicolon => (),
// stmt <error> // stmt <error>
(Token::LexError(err), pos) => return Err(err.into_err(*pos)), (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)),
// stmt ??? // stmt ???
(_, pos) => { (_, pos) => {
// Semicolons are not optional between statements // Semicolons are not optional between statements

View File

@ -36,10 +36,10 @@ pub enum EvalAltResult {
/// An error has occurred inside a called function. /// An error has occurred inside a called function.
/// Wrapped values are the function name and the interior error. /// Wrapped values are the function name and the interior error.
ErrorInFunctionCall(String, Box<EvalAltResult>, Position), ErrorInFunctionCall(String, Box<EvalAltResult>, Position),
/// Usage of an unknown module. Wrapped value is the module name. /// Usage of an unknown [module][crate::Module]. Wrapped value is the [module][crate::Module] name.
ErrorModuleNotFound(String, Position), ErrorModuleNotFound(String, Position),
/// An error has occurred while loading a module. /// An error has occurred while loading a [module][crate::Module].
/// Wrapped value are the module name and the interior error. /// Wrapped value are the [module][crate::Module] name and the interior error.
ErrorInModule(String, Box<EvalAltResult>, Position), ErrorInModule(String, Box<EvalAltResult>, Position),
/// Access to `this` that is not bound. /// Access to `this` that is not bound.
ErrorUnboundThis(Position), ErrorUnboundThis(Position),
@ -72,7 +72,7 @@ pub enum EvalAltResult {
ErrorArithmetic(String, Position), ErrorArithmetic(String, Position),
/// Number of operations over maximum limit. /// Number of operations over maximum limit.
ErrorTooManyOperations(Position), ErrorTooManyOperations(Position),
/// Modules over maximum limit. /// [Modules][crate::Module] over maximum limit.
ErrorTooManyModules(Position), ErrorTooManyModules(Position),
/// Call stack over maximum limit. /// Call stack over maximum limit.
ErrorStackOverflow(Position), ErrorStackOverflow(Position),
@ -314,7 +314,7 @@ impl EvalAltResult {
_ => false, _ => false,
} }
} }
/// Get the [`Position`] of this error. /// Get the [position][Position] of this error.
pub fn position(&self) -> Position { pub fn position(&self) -> Position {
match self { match self {
Self::ErrorSystem(_, _) => Position::NONE, Self::ErrorSystem(_, _) => Position::NONE,
@ -347,7 +347,7 @@ impl EvalAltResult {
| Self::Return(_, pos) => *pos, | Self::Return(_, pos) => *pos,
} }
} }
/// Override the [`Position`] of this error. /// Override the [position][Position] of this error.
pub fn set_position(&mut self, new_position: Position) { pub fn set_position(&mut self, new_position: Position) {
match self { match self {
Self::ErrorSystem(_, _) => (), Self::ErrorSystem(_, _) => (),

View File

@ -30,7 +30,7 @@ impl EntryType {
/// # Thread Safety /// # Thread Safety
/// ///
/// Currently, [`Scope`] is neither [`Send`] nor [`Sync`]. /// Currently, [`Scope`] is neither [`Send`] nor [`Sync`].
/// Turn on the [`Sync`] feature to make it [`Send`] `+` [`Sync`]. /// Turn on the `sync` feature to make it [`Send`] `+` [`Sync`].
/// ///
/// # Example /// # Example
/// ///

View File

@ -61,7 +61,7 @@ impl Expression<'_> {
} }
impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_, '_> { impl EvalContext<'_, '_, '_, '_, '_, '_, '_, '_, '_> {
/// Evaluate an expression tree. /// Evaluate an [expression tree][Expression].
/// ///
/// ## WARNING - Low Level API /// ## WARNING - Low Level API
/// ///