Compare commits

...

16 Commits

Author SHA1 Message Date
939048418b Update actions/cache action to v5 2025-12-12 01:57:09 +00:00
2fe191f2a3 Update actions/checkout action to v6 2025-11-21 01:53:48 +00:00
b1a5f47b05 Update all dependencies 2025-11-13 02:40:33 +00:00
013075bc82 Merge pull request 'Configure Renovate' (#1) from renovate/configure into main
Reviewed-on: https://git.front.kjuulh.io/kjuulh/rhai/pulls/1
2023-08-08 12:13:13 +00:00
9f0bb3e693 Add renovate.json 2023-07-03 10:44:17 +00:00
Stephen Chung
ca18cdd7f4 Merge pull request #733 from schungx/master
Fix bug.
2023-06-27 22:49:00 +08:00
Stephen Chung
2474c1fec1 Fix bug. 2023-06-27 17:14:18 +08:00
Stephen Chung
541844e1e1 Remove unnecessary gates. 2023-06-27 16:53:21 +08:00
Stephen Chung
172bc14996 Bump version. 2023-06-26 08:48:22 +08:00
Stephen Chung
4627fb22a5 Merge pull request #731 from schungx/master
Bug fix.
2023-06-25 21:37:18 +08:00
Stephen Chung
1326ab933c Change version to 1.15.1. 2023-06-25 21:36:56 +08:00
Stephen Chung
03b1a1cea2 Fix bug in Dynamic::deep_scan. 2023-06-24 19:14:18 +08:00
Stephen Chung
ee64fd90aa Bump version. 2023-06-18 20:53:49 +08:00
Stephen Chung
fd162ab99f Merge pull request #728 from schungx/master
Fix tests output.
2023-06-15 21:41:35 +08:00
Stephen Chung
1728de7dcd Fix tests output. 2023-06-15 11:06:14 +08:00
Stephen Chung
d12b124f67 Merge pull request #726 from schungx/master
Fix static hashing key bug.
2023-06-15 11:01:41 +08:00
14 changed files with 71 additions and 35 deletions

View File

@@ -10,7 +10,7 @@ jobs:
name: Run Rust benchmark name: Run Rust benchmark
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v6
- run: rustup toolchain update nightly && rustup default nightly - run: rustup toolchain update nightly && rustup default nightly
- name: Run benchmark - name: Run benchmark
run: cargo +nightly bench --features decimal,metadata,serde,debugging | tee output.txt run: cargo +nightly bench --features decimal,metadata,serde,debugging | tee output.txt

View File

@@ -14,8 +14,8 @@ jobs:
msrv: msrv:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: actions/cache@v1 - uses: actions/cache@v5
with: with:
path: | path: |
~/.cargo/bin ~/.cargo/bin
@@ -76,7 +76,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v6
- name: Setup Toolchain - name: Setup Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@@ -101,7 +101,7 @@ jobs:
#- {os: macos-latest, flags: "--profile macos", experimental: false} #- {os: macos-latest, flags: "--profile macos", experimental: false}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v6
- name: Setup Toolchain - name: Setup Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@@ -128,7 +128,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v6
- name: Setup Generic Wasm Toolchain - name: Setup Generic Wasm Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@@ -153,7 +153,7 @@ jobs:
continue-on-error: true continue-on-error: true
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v6
- name: Setup Toolchain - name: Setup Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
@@ -182,7 +182,7 @@ jobs:
- {toolchain: stable, os: windows-latest, experimental: false, flags: "--features metadata"} - {toolchain: stable, os: windows-latest, experimental: false, flags: "--features metadata"}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v6
- name: Setup Toolchain - name: Setup Toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:

View File

@@ -13,7 +13,7 @@ jobs:
feature_powerset: feature_powerset:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1 - uses: dtolnay/rust-toolchain@v1
with: with:
toolchain: stable toolchain: stable

View File

@@ -1,6 +1,24 @@
Rhai Release Notes Rhai Release Notes
================== ==================
Version 1.16.0
==============
Bug fixes
---------
* Fixes a panic when using `this` as the first parameter in a namespace-qualified function call.
Version 1.15.1
==============
Bug fixes
---------
* `Dynamic::deep_scan` is fixed so now it properly scans arrays, object maps and function pointers embedded inside data.
Version 1.15.0 Version 1.15.0
============== ==============
@@ -14,6 +32,7 @@ Enhancements
* Expressions involving `this` should now run slightly faster due to a dedicated `AST` node `ThisPtr`. * Expressions involving `this` should now run slightly faster due to a dedicated `AST` node `ThisPtr`.
* A `take` function is added to the standard library to take ownership of any data (replacing with `()`) in order to avoid cloning. * A `take` function is added to the standard library to take ownership of any data (replacing with `()`) in order to avoid cloning.
* `Dynamic::take` is added to take ownership of the data (replacing with `()`) in order to avoid cloning.
* `EvalAltResult::ErrorMismatchOutputType` now gives a better name for the requested generic type (e.g. `&str` is now `&str` and not `string`). * `EvalAltResult::ErrorMismatchOutputType` now gives a better name for the requested generic type (e.g. `&str` is now `&str` and not `string`).

View File

@@ -3,7 +3,7 @@ members = [".", "codegen"]
[package] [package]
name = "rhai" name = "rhai"
version = "1.15.0" version = "1.16.0"
rust-version = "1.61.0" rust-version = "1.61.0"
edition = "2018" edition = "2018"
resolver = "2" resolver = "2"
@@ -21,20 +21,20 @@ categories = ["no-std", "embedded", "wasm", "parser-implementations"]
smallvec = { version = "1.7", default-features = false, features = ["union", "const_new", "const_generics"] } smallvec = { version = "1.7", default-features = false, features = ["union", "const_new", "const_generics"] }
ahash = { version = "0.8.2", default-features = false, features = ["compile-time-rng"] } ahash = { version = "0.8.2", default-features = false, features = ["compile-time-rng"] }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
bitflags = { version = "1", default-features = false } bitflags = { version = "2", default-features = false }
smartstring = { version = "1", default-features = false } smartstring = { version = "1", default-features = false }
rhai_codegen = { version = "1.5.0", path = "codegen", default-features = false } rhai_codegen = { version = "1.5.0", path = "codegen", default-features = false }
no-std-compat = { git = "https://gitlab.com/jD91mZM2/no-std-compat", version = "0.4.1", default-features = false, features = ["alloc"], optional = true } no-std-compat = { git = "https://gitlab.com/jD91mZM2/no-std-compat", version = "0.4.1", default-features = false, features = ["alloc"], optional = true }
libm = { version = "0.2", default-features = false, optional = true } libm = { version = "0.2", default-features = false, optional = true }
hashbrown = { version = "0.13", optional = true } hashbrown = { version = "0.16", optional = true }
core-error = { version = "0.0", default-features = false, features = ["alloc"], optional = true } core-error = { version = "0.0", default-features = false, features = ["alloc"], optional = true }
serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"], optional = true }
serde_json = { version = "1.0", default-features = false, features = ["alloc"], optional = true } serde_json = { version = "1.0", default-features = false, features = ["alloc"], optional = true }
unicode-xid = { version = "0.2", default-features = false, optional = true } unicode-xid = { version = "0.2", default-features = false, optional = true }
rust_decimal = { version = "1.16", default-features = false, features = ["maths"], optional = true } rust_decimal = { version = "1.16", default-features = false, features = ["maths"], optional = true }
getrandom = { version = "0.2", optional = true } getrandom = { version = "0.3", optional = true }
rustyline = { version = "11", optional = true } rustyline = { version = "17", optional = true }
document-features = { version = "0.2", optional = true } document-features = { version = "0.2", optional = true }
[dev-dependencies] [dev-dependencies]

View File

@@ -20,7 +20,7 @@ metadata = []
[dependencies] [dependencies]
proc-macro2 = "1" proc-macro2 = "1"
syn = { version = "1.0", features = ["full", "parsing", "printing", "proc-macro", "extra-traits"] } syn = { version = "2.0", features = ["full", "parsing", "printing", "proc-macro", "extra-traits"] }
quote = "1" quote = "1"
[dev-dependencies] [dev-dependencies]

View File

@@ -11,5 +11,6 @@ note: required by a bound in `rhai::Dynamic::cast`
| ^^^^^ required by this bound in `Dynamic::cast` | ^^^^^ required by this bound in `Dynamic::cast`
help: consider annotating `NonClonable` with `#[derive(Clone)]` help: consider annotating `NonClonable` with `#[derive(Clone)]`
| |
3 | #[derive(Clone)] 3 + #[derive(Clone)]
4 | struct NonClonable {
| |

View File

@@ -11,5 +11,6 @@ note: required by a bound in `rhai::Dynamic::cast`
| ^^^^^ required by this bound in `Dynamic::cast` | ^^^^^ required by this bound in `Dynamic::cast`
help: consider annotating `NonClonable` with `#[derive(Clone)]` help: consider annotating `NonClonable` with `#[derive(Clone)]`
| |
3 | #[derive(Clone)] 3 + #[derive(Clone)]
4 | struct NonClonable {
| |

View File

@@ -14,5 +14,6 @@ note: required by a bound in `rhai::Dynamic::from`
= note: this error originates in the attribute macro `export_fn` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the attribute macro `export_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `NonClonable` with `#[derive(Clone)]` help: consider annotating `NonClonable` with `#[derive(Clone)]`
| |
3 | #[derive(Clone)] 3 + #[derive(Clone)]
4 | struct NonClonable {
| |

View File

@@ -15,5 +15,6 @@ note: required by a bound in `rhai::Dynamic::from`
= note: this error originates in the attribute macro `export_module` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the attribute macro `export_module` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `NonClonable` with `#[derive(Clone)]` help: consider annotating `NonClonable` with `#[derive(Clone)]`
| |
3 | #[derive(Clone)] 3 + #[derive(Clone)]
4 | struct NonClonable {
| |

View File

@@ -13,9 +13,9 @@ help: a struct with a similar name exists
| ~~~~~ | ~~~~~
help: consider importing one of these items help: consider importing one of these items
| |
11 | use core::fmt::Pointer; 11 + use core::fmt::Pointer;
| |
11 | use std::fmt::Pointer; 11 + use std::fmt::Pointer;
| |
11 | use syn::__private::fmt::Pointer; 11 + use syn::__private::fmt::Pointer;
| |

3
renovate.json Normal file
View File

@@ -0,0 +1,3 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View File

@@ -1289,15 +1289,17 @@ impl Engine {
// Call with blank scope // Call with blank scope
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
let this_ptr_not_shared = this_ptr.as_ref().map_or(false, |v| !v.is_shared()); let has_non_shared_this_ptr = this_ptr.as_ref().map_or(false, |v| !v.is_shared());
#[cfg(feature = "no_closure")] #[cfg(feature = "no_closure")]
let this_ptr_not_shared = true; let has_non_shared_this_ptr = this_ptr.is_some();
// If the first argument is a variable, and there are no curried arguments, // If the first argument is a variable, and there are no curried arguments,
// convert to method-call style in order to leverage potential &mut first argument // convert to method-call style in order to leverage potential &mut first argument
// and avoid cloning the value. // and avoid cloning the value.
match first_arg { match first_arg {
Some(_first_expr @ Expr::ThisPtr(pos)) if curry.is_empty() && this_ptr_not_shared => { Some(_first_expr @ Expr::ThisPtr(pos))
if curry.is_empty() && has_non_shared_this_ptr =>
{
// Turn it into a method call only if the object is not shared // Turn it into a method call only if the object is not shared
self.track_operation(global, *pos)?; self.track_operation(global, *pos)?;
@@ -1381,21 +1383,30 @@ impl Engine {
let mut first_arg_value = None; let mut first_arg_value = None;
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
let this_ptr_not_shared = this_ptr.as_ref().map_or(false, |v| !v.is_shared()); let has_non_shared_this_ptr = this_ptr.as_ref().map_or(false, |v| !v.is_shared());
#[cfg(feature = "no_closure")] #[cfg(feature = "no_closure")]
let this_ptr_not_shared = true; let has_non_shared_this_ptr = this_ptr.is_some();
// See if the first argument is a variable. // See if the first argument is a variable.
// If so, convert to method-call style in order to leverage potential // If so, convert to method-call style in order to leverage potential
// &mut first argument and avoid cloning the value. // &mut first argument and avoid cloning the value.
match args_expr.get(0) { match args_expr.get(0) {
Some(_first_expr @ Expr::ThisPtr(pos)) if this_ptr_not_shared => { Some(_first_expr @ Expr::ThisPtr(pos)) if has_non_shared_this_ptr => {
self.track_operation(global, *pos)?; self.track_operation(global, *pos)?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), _first_expr)?; self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), _first_expr)?;
// Turn it into a method call only if the object is not shared // The first value is a placeholder (for later if it needs to be cloned)
arg_values.push(Dynamic::UNIT);
for expr in args_expr.iter().skip(1) {
let (value, ..) =
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
arg_values.push(value.flatten());
}
// func(x, ...) -> x.func(...)
let (first, rest) = arg_values.split_first_mut().unwrap(); let (first, rest) = arg_values.split_first_mut().unwrap();
first_arg_value = Some(first); first_arg_value = Some(first);
args.push(this_ptr.unwrap()); args.push(this_ptr.unwrap());
@@ -1407,7 +1418,7 @@ impl Engine {
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_expr)?; self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_expr)?;
// func(x, ...) -> x.func(...) // The first value is a placeholder (for later if it needs to be cloned)
arg_values.push(Dynamic::UNIT); arg_values.push(Dynamic::UNIT);
for expr in args_expr.iter().skip(1) { for expr in args_expr.iter().skip(1) {
@@ -1423,6 +1434,7 @@ impl Engine {
args.extend(arg_values.iter_mut()); args.extend(arg_values.iter_mut());
} else { } else {
// Turn it into a method call only if the object is not shared and not a simple value // Turn it into a method call only if the object is not shared and not a simple value
// func(x, ...) -> x.func(...)
let (first, rest) = arg_values.split_first_mut().unwrap(); let (first, rest) = arg_values.split_first_mut().unwrap();
first_arg_value = Some(first); first_arg_value = Some(first);
let obj_ref = target.take_ref().expect("ref"); let obj_ref = target.take_ref().expect("ref");

View File

@@ -246,10 +246,7 @@ impl Dynamic {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub const fn is_shared(&self) -> bool { pub const fn is_shared(&self) -> bool {
#[cfg(not(feature = "no_closure"))] matches!(self.0, Union::Shared(..))
return matches!(self.0, Union::Shared(..));
#[cfg(feature = "no_closure")]
return false;
} }
/// Is the value held by this [`Dynamic`] a particular type? /// Is the value held by this [`Dynamic`] a particular type?
/// ///
@@ -2107,6 +2104,8 @@ impl Dynamic {
#[allow(clippy::only_used_in_recursion)] #[allow(clippy::only_used_in_recursion)]
pub fn deep_scan(&mut self, mut filter: impl FnMut(&mut Self)) { pub fn deep_scan(&mut self, mut filter: impl FnMut(&mut Self)) {
fn scan_inner(value: &mut Dynamic, filter: &mut impl FnMut(&mut Dynamic)) { fn scan_inner(value: &mut Dynamic, filter: &mut impl FnMut(&mut Dynamic)) {
filter(value);
match &mut value.0 { match &mut value.0 {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Union::Array(a, ..) => a.iter_mut().for_each(|v| scan_inner(v, filter)), Union::Array(a, ..) => a.iter_mut().for_each(|v| scan_inner(v, filter)),
@@ -2117,7 +2116,6 @@ impl Dynamic {
} }
} }
filter(self);
scan_inner(self, &mut filter); scan_inner(self, &mut filter);
} }
} }