From 86d86a85e46ffe85a50389ae45ff15cba1c3a1bc Mon Sep 17 00:00:00 2001 From: Nathan Kent Date: Sat, 5 Feb 2022 16:29:05 -0800 Subject: [PATCH 01/12] Remove unsound casting functions The casting functions in `unsafe.rs` were unsound (i.e., they allowed safe code to cause undefined behavior). While they did appear to be used in a way that wouldn't cause UB the fact that there exists unsound functions is unsettling. This commit removes those functions and replaces it with a macro that performs the same reification - the difference is that the macro call will also include the checks which are required to prevent UB. A macro was chosen instead of a function for two reasons: 1. A macro can keep the same code generation whereas a function would require going through an `Option` which has negative impacts on code generation (niche values cause poor DCE). 2. There exist other `unsafe` code blocks in the crate and an attempt to make Rhai 100% safe is completely out-of-scope for this merge request, so we may as well use `unsafe` in the macro. Regarding (2) above, I may come back at a later date with a 100% safe `reify` function but only once the other `unsafe` blocks are removed. For posterity, said function would look something like: ```rust fn reify(value: A) -> Option { let mut v = Some(value); let v: &mut dyn Any = &mut v; v.downcast_mut::>().map(Option::take) } ``` --- src/README.md | 2 +- src/api/custom_syntax.rs | 58 ++++------- src/func/register.rs | 8 +- src/lib.rs | 2 +- src/reify.rs | 26 +++++ src/types/dynamic.rs | 210 +++++++++------------------------------ src/unsafe.rs | 54 ---------- 7 files changed, 94 insertions(+), 266 deletions(-) create mode 100644 src/reify.rs delete mode 100644 src/unsafe.rs diff --git a/src/README.md b/src/README.md index 5feefa30..fc1d7bbf 100644 --- a/src/README.md +++ b/src/README.md @@ -11,7 +11,7 @@ Root Sources | `tokenizer.rs` | Script tokenizer/lexer | | `parser.rs` | Script parser | | `optimizer.rs` | Script optimizer | -| `unsafe.rs` | `unsafe` functions | +| `reify.rs` | Utilities for making generic types concrete | | `tests.rs` | Unit tests (not integration tests, which are in the `rhai/tests` sub-directory) | diff --git a/src/api/custom_syntax.rs b/src/api/custom_syntax.rs index 0411f3f0..d5263ac4 100644 --- a/src/api/custom_syntax.rs +++ b/src/api/custom_syntax.rs @@ -3,16 +3,15 @@ use crate::ast::Expr; use crate::func::native::SendSync; use crate::parser::ParseResult; -use crate::r#unsafe::unsafe_try_cast; use crate::tokenizer::{is_valid_identifier, Token}; use crate::types::dynamic::Variant; use crate::{ Engine, EvalContext, Identifier, ImmutableString, LexError, Position, RhaiResult, Shared, - StaticVec, INT, + StaticVec, reify, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::{any::TypeId, ops::Deref}; +use std::ops::Deref; /// Collection of special markers for custom syntax definition. pub mod markers { @@ -94,46 +93,23 @@ impl Expression<'_> { #[must_use] pub fn get_literal_value(&self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. + match self.0 { + Expr::IntegerConstant(x, _) => reify!(x, |x: T| Some(x), || None), - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Expr::IntegerConstant(x, _) => unsafe_try_cast(*x), - _ => None, - }; + #[cfg(not(feature = "no_float"))] + Expr::FloatConstant(x, _) => reify!(x, |x: T| Some(x), || None), + + Expr::CharConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::StringConstant(x, _) => reify!(x.clone(), |x: T| Some(x), || None), + Expr::Variable(_, _, x) => { + let x = Into::::into(&x.2); + reify!(x, |x: T| Some(x), || None) + } + Expr::BoolConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::Unit(_) => reify!((), |x: T| Some(x), || None), + + _ => None, } - #[cfg(not(feature = "no_float"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Expr::FloatConstant(x, _) => unsafe_try_cast(*x), - _ => None, - }; - } - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Expr::CharConstant(x, _) => unsafe_try_cast(*x), - _ => None, - }; - } - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Expr::StringConstant(x, _) => unsafe_try_cast(x.clone()), - Expr::Variable(_, _, x) => unsafe_try_cast(Into::::into(&x.2)), - _ => None, - }; - } - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Expr::BoolConstant(x, _) => unsafe_try_cast(*x), - _ => None, - }; - } - if TypeId::of::() == TypeId::of::<()>() { - return match self.0 { - Expr::Unit(_) => unsafe_try_cast(()), - _ => None, - }; - } - None } } diff --git a/src/func/register.rs b/src/func/register.rs index 90a1e01c..d2171cfb 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -5,10 +5,9 @@ use super::call::FnCallArgs; use super::callable_function::CallableFunction; use super::native::{FnAny, SendSync}; -use crate::r#unsafe::unsafe_cast; use crate::tokenizer::Position; use crate::types::dynamic::{DynamicWriteLock, Variant}; -use crate::{Dynamic, NativeCallContext, RhaiResultOf, ERR}; +use crate::{Dynamic, NativeCallContext, RhaiResultOf, ERR, reify}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{any::TypeId, mem}; @@ -46,11 +45,12 @@ pub fn by_value(data: &mut Dynamic) -> T { // If T is `&str`, data must be `ImmutableString`, so map directly to it data.flatten_in_place(); let ref_str = data.as_str_ref().expect("&str"); - let ref_t = unsafe { mem::transmute::<_, &T>(&ref_str) }; + let ref_t = reify!(ref_str, |ref_t: &T| ref_t, || unreachable!()); ref_t.clone() } else if TypeId::of::() == TypeId::of::() { // If T is `String`, data must be `ImmutableString`, so map directly to it - unsafe_cast(mem::take(data).into_string().expect("`ImmutableString`")) + let t = mem::take(data).into_string().expect("`ImmutableString`"); + reify!(t, |t: T| t, || unreachable!()) } else { // We consume the argument and then replace it with () - the argument is not supposed to be used again. // This way, we avoid having to clone the argument again, because it is already a clone when passed here. diff --git a/src/lib.rs b/src/lib.rs index ea94ed65..98438971 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,7 @@ extern crate no_std_compat as std; use std::prelude::v1::*; // Internal modules +mod reify; mod api; mod ast; @@ -81,7 +82,6 @@ mod parser; mod tests; mod tokenizer; mod types; -mod r#unsafe; /// Error encountered when parsing a script. type PERR = ParseErrorType; diff --git a/src/reify.rs b/src/reify.rs new file mode 100644 index 00000000..82d3bdbe --- /dev/null +++ b/src/reify.rs @@ -0,0 +1,26 @@ +/// Runs `$code` if `$old` is of type `$t`. +#[macro_export] +macro_rules! reify { + ($old:ident, |$new:ident : $t:ty| $code:expr, || $fallback:expr) => {{ + #[allow(unused_imports)] + use ::std::{any::{Any, TypeId}, mem::{ManuallyDrop, transmute_copy}}; + if TypeId::of::<$t>() == $old.type_id() { + // SAFETY: This is safe because we check to make sure the two types are + // actually the same type. + let $new: $t = unsafe { transmute_copy(&ManuallyDrop::new($old)) }; + $code + } else { + $fallback + } + }}; + ($old:expr, |$new:ident : $t:ty| $code:expr, || $fallback:expr) => {{ + let old = $old; + reify!(old, |$new : $t| $code, || $fallback) + }}; + ($old:ident, |$new:ident : $t:ty| $code:expr) => { + reify!($old, |$new : $t| $code, || ()) + }; + ($old:expr, |$new:ident : $t:ty| $code:expr) => { + reify!($old, |$new : $t| $code, || ()) + }; +} diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 48d0d124..489e4884 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -1,8 +1,7 @@ //! Helper module which defines the [`Any`] trait to to allow dynamic value handling. use crate::func::native::SendSync; -use crate::r#unsafe::{unsafe_cast, unsafe_cast_box, unsafe_try_cast}; -use crate::{ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; +use crate::{ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT, reify}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{ @@ -1137,10 +1136,6 @@ impl Dynamic { } /// Create a [`Dynamic`] from any type. A [`Dynamic`] value is simply returned as is. /// - /// # Safety - /// - /// This type uses some unsafe code, mainly for type casting. - /// /// # Notes /// /// Beware that you need to pass in an [`Array`][crate::Array] type for it to be recognized as an [`Array`][crate::Array]. @@ -1175,74 +1170,37 @@ impl Dynamic { pub fn from(value: T) -> Self { // Coded this way in order to maximally leverage potentials for dead-code removal. - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, Dynamic>(value); - } + reify!(value, |v: Dynamic| return v); + reify!(value, |v: INT| return v.into()); - let val = value.as_any(); - - if TypeId::of::() == TypeId::of::() { - return (*val.downcast_ref::().expect(CHECKED)).into(); - } #[cfg(not(feature = "no_float"))] - if TypeId::of::() == TypeId::of::() { - return (*val.downcast_ref::().expect(CHECKED)).into(); - } + reify!(value, |v: crate::FLOAT| return v.into()); + #[cfg(feature = "decimal")] - if TypeId::of::() == TypeId::of::() { - return (*val.downcast_ref::().expect(CHECKED)).into(); - } - if TypeId::of::() == TypeId::of::() { - return (*val.downcast_ref::().expect(CHECKED)).into(); - } - if TypeId::of::() == TypeId::of::() { - return (*val.downcast_ref::().expect(CHECKED)).into(); - } - if TypeId::of::() == TypeId::of::() { - return val - .downcast_ref::() - .expect(CHECKED) - .clone() - .into(); - } - if TypeId::of::() == TypeId::of::<&str>() { - return val.downcast_ref::<&str>().expect(CHECKED).deref().into(); - } - if TypeId::of::() == TypeId::of::<()>() { - return ().into(); - } + reify!(value, |v: rust_decimal::Decimal| return v.into()); - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, String>(value).into(); - } - #[cfg(not(feature = "no_float"))] - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, crate::FLOAT>(value).into(); - } + reify!(value, |v: bool| return v.into()); + reify!(value, |v: char| return v.into()); + reify!(value, |v: ImmutableString| return v.into()); + reify!(value, |v: &str| return v.into()); + reify!(value, |v: ()| return v.into()); + + reify!(value, |v: String| return v.into()); #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, crate::Array>(value).into(); - } + reify!(value, |v: crate::Array| return v.into()); #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - return Dynamic::from_blob(unsafe_cast::<_, crate::Blob>(value)); // don't use blob.into() because it'll be converted into an Array - } + reify!(value, |v: crate::Blob| { + // don't use blob.into() because it'll be converted into an Array + return Dynamic::from_blob(v); + }); #[cfg(not(feature = "no_object"))] - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, crate::Map>(value).into(); - } - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, FnPtr>(value).into(); - } + reify!(value, |v: crate::Map| return v.into()); + reify!(value, |v: FnPtr| return v.into()); #[cfg(not(feature = "no_std"))] - if TypeId::of::() == TypeId::of::() { - return unsafe_cast::<_, Instant>(value).into(); - } + reify!(value, |v: Instant| return v.into()); #[cfg(not(feature = "no_closure"))] - if TypeId::of::() == TypeId::of::>>() { - return unsafe_cast::<_, crate::Shared>>(value).into(); - } + reify!(value, |v: crate::Shared>| return v.into()); Self(Union::Variant( Box::new(Box::new(value)), @@ -1311,112 +1269,34 @@ impl Dynamic { return self.flatten().try_cast::(); } - if TypeId::of::() == TypeId::of::() { - return unsafe_try_cast::<_, T>(self); - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Int(v, _, _) => unsafe_try_cast(v), - _ => None, - }; - } - - #[cfg(not(feature = "no_float"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Float(v, _, _) => unsafe_try_cast(*v), - _ => None, - }; - } - - #[cfg(feature = "decimal")] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Decimal(v, _, _) => unsafe_try_cast(*v), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Bool(v, _, _) => unsafe_try_cast(v), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Str(v, _, _) => unsafe_try_cast(v), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Str(v, _, _) => unsafe_try_cast(v.to_string()), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Char(v, _, _) => unsafe_try_cast(v), - _ => None, - }; - } - - #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Array(v, _, _) => unsafe_cast_box::<_, T>(v), - _ => None, - }; - } - - #[cfg(not(feature = "no_index"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Blob(v, _, _) => unsafe_cast_box::<_, T>(v), - _ => None, - }; - } - - #[cfg(not(feature = "no_object"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::Map(v, _, _) => unsafe_cast_box::<_, T>(v), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::FnPtr(v, _, _) => unsafe_cast_box::<_, T>(v), - _ => None, - }; - } - - #[cfg(not(feature = "no_std"))] - if TypeId::of::() == TypeId::of::() { - return match self.0 { - Union::TimeStamp(v, _, _) => unsafe_cast_box::<_, T>(v), - _ => None, - }; - } - - if TypeId::of::() == TypeId::of::<()>() { - return match self.0 { - Union::Unit(v, _, _) => unsafe_try_cast(v), - _ => None, - }; - } + reify!(self, |v: T| return Some(v)); match self.0 { + Union::Int(v, ..) => reify!(v, |v: T| Some(v), || None), + #[cfg(not(feature = "no_float"))] + Union::Float(v, ..) => reify!(v, |v: T| Some(v), || None), + #[cfg(feature = "decimal")] + Union::Decimal(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Bool(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Str(v, ..) => { + reify!(v, |v: T| Some(v), || { + reify!(v.to_string(), |v: T| Some(v), || None) + }) + }, + Union::Char(v, ..) => reify!(v, |v: T| Some(v), || None), + #[cfg(not(feature = "no_index"))] + Union::Array(v, ..) => reify!(v, |v: Box| Some(*v), || None), + #[cfg(not(feature = "no_index"))] + Union::Blob(v, ..) => reify!(v, |v: Box| Some(*v), || None), + #[cfg(not(feature = "no_object"))] + Union::Map(v, ..) => reify!(v, |v: Box| Some(*v), || None), + Union::FnPtr(v, ..) => reify!(v, |v: Box| Some(*v), || None), + #[cfg(not(feature = "no_std"))] + Union::TimeStamp(v, ..) => reify!(v, |v: Box| Some(*v), || None), + Union::Unit(v, ..) => reify!(v, |v: T| Some(v), || None), Union::Variant(v, _, _) => (*v).as_boxed_any().downcast().ok().map(|x| *x), #[cfg(not(feature = "no_closure"))] Union::Shared(_, _, _) => unreachable!("Union::Shared case should be already handled"), - _ => None, } } /// Convert the [`Dynamic`] value into a specific type. diff --git a/src/unsafe.rs b/src/unsafe.rs deleted file mode 100644 index 9c1eb467..00000000 --- a/src/unsafe.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! A helper module containing unsafe utility functions. - -#[cfg(feature = "no_std")] -use std::prelude::v1::*; -use std::{ - any::{Any, TypeId}, - mem, ptr, -}; - -/// Cast a type into another type. -/// -/// # Undefined Behavior -/// -/// It is UB if the types are not compatible. -#[inline(always)] -#[must_use] -pub fn unsafe_cast(a: A) -> B { - unsafe { - let ret: B = ptr::read(&a as *const _ as *const B); - // We explicitly forget the value immediately after moving out, - // removing any chance of a destructor running or value otherwise - // being used again. - mem::forget(a); - ret - } -} - -/// Cast a type into another type. -#[inline(always)] -#[must_use] -pub fn unsafe_try_cast(a: A) -> Option { - if TypeId::of::() == a.type_id() { - // SAFETY: Just checked we have the right type. - Some(unsafe_cast(a)) - } else { - None - } -} - -/// Cast a Boxed type into another type. -#[inline(always)] -#[must_use] -pub fn unsafe_cast_box(item: Box) -> Option { - // Only allow casting to the exact same type - if TypeId::of::() == TypeId::of::() { - // SAFETY: just checked whether we are pointing to the correct type - unsafe { - let raw: *mut dyn Any = Box::into_raw(item as Box); - Some(*Box::from_raw(raw as *mut T)) - } - } else { - None - } -} From cfbf0397a6d625bc88e637af5bec2dc2ef8e5120 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 6 Feb 2022 21:24:02 +0800 Subject: [PATCH 02/12] Better position of assignment errors. --- src/parser.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index ae8de862..ad02c52c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1758,7 +1758,7 @@ fn make_assignment_stmt( } Expr::Property(_, _) => None, // Anything other than a property after dotting (e.g. a method call) is not an l-value - ref e => Some(e.start_position()), + ref e => Some(e.position()), }, Expr::Index(x, term, _) | Expr::Dot(x, term, _) => match x.lhs { Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"), @@ -1767,7 +1767,7 @@ fn make_assignment_stmt( }, Expr::Property(_, _) if parent_is_dot => None, Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"), - e if parent_is_dot => Some(e.start_position()), + e if parent_is_dot => Some(e.position()), _ => None, } } @@ -1819,8 +1819,10 @@ fn make_assignment_stmt( op_pos, )), // expr[???] = rhs, expr.??? = rhs - ref expr => Err(PERR::AssignmentToInvalidLHS("".to_string()) - .into_err(expr.start_position())), + ref expr => { + Err(PERR::AssignmentToInvalidLHS("".to_string()) + .into_err(expr.position())) + } } } Some(err_pos) => { @@ -1835,7 +1837,7 @@ fn make_assignment_stmt( ) .into_err(op_pos)), // expr = rhs - _ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.start_position())), + _ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.position())), } } From becbfa8930321d64df58913a953a15d2bbbe9915 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sun, 6 Feb 2022 23:02:59 +0800 Subject: [PATCH 03/12] Fix errors. --- src/api/custom_syntax.rs | 16 ++++++++-------- src/func/register.rs | 5 +++-- src/lib.rs | 3 +-- src/reify.rs | 32 ++++++++++++++++++++++++++------ src/types/dynamic.rs | 26 +++++++++++--------------- 5 files changed, 49 insertions(+), 33 deletions(-) diff --git a/src/api/custom_syntax.rs b/src/api/custom_syntax.rs index d5263ac4..5e6232b6 100644 --- a/src/api/custom_syntax.rs +++ b/src/api/custom_syntax.rs @@ -6,12 +6,12 @@ use crate::parser::ParseResult; use crate::tokenizer::{is_valid_identifier, Token}; use crate::types::dynamic::Variant; use crate::{ - Engine, EvalContext, Identifier, ImmutableString, LexError, Position, RhaiResult, Shared, - StaticVec, reify, + reify, Engine, EvalContext, Identifier, ImmutableString, LexError, Position, RhaiResult, + Shared, StaticVec, }; +use std::ops::Deref; #[cfg(feature = "no_std")] use std::prelude::v1::*; -use std::ops::Deref; /// Collection of special markers for custom syntax definition. pub mod markers { @@ -94,18 +94,18 @@ impl Expression<'_> { pub fn get_literal_value(&self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. match self.0 { - Expr::IntegerConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::IntegerConstant(x, _) => reify!(*x, |x: T| Some(x), || None), #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::FloatConstant(x, _) => reify!(*x, |x: T| Some(x), || None), - Expr::CharConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::CharConstant(x, _) => reify!(*x, |x: T| Some(x), || None), Expr::StringConstant(x, _) => reify!(x.clone(), |x: T| Some(x), || None), Expr::Variable(_, _, x) => { - let x = Into::::into(&x.2); + let x: ImmutableString = x.2.clone().into(); reify!(x, |x: T| Some(x), || None) } - Expr::BoolConstant(x, _) => reify!(x, |x: T| Some(x), || None), + Expr::BoolConstant(x, _) => reify!(*x, |x: T| Some(x), || None), Expr::Unit(_) => reify!((), |x: T| Some(x), || None), _ => None, diff --git a/src/func/register.rs b/src/func/register.rs index d2171cfb..b87e0bec 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -7,7 +7,7 @@ use super::callable_function::CallableFunction; use super::native::{FnAny, SendSync}; use crate::tokenizer::Position; use crate::types::dynamic::{DynamicWriteLock, Variant}; -use crate::{Dynamic, NativeCallContext, RhaiResultOf, ERR, reify}; +use crate::{reify, Dynamic, NativeCallContext, RhaiResultOf, ERR}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{any::TypeId, mem}; @@ -45,7 +45,8 @@ pub fn by_value(data: &mut Dynamic) -> T { // If T is `&str`, data must be `ImmutableString`, so map directly to it data.flatten_in_place(); let ref_str = data.as_str_ref().expect("&str"); - let ref_t = reify!(ref_str, |ref_t: &T| ref_t, || unreachable!()); + //let ref_t = reify!(&ref_str, |ref_t: &T| ref_t, || unreachable!()); + let ref_t = unsafe { mem::transmute::<_, &T>(&ref_str) }; ref_t.clone() } else if TypeId::of::() == TypeId::of::() { // If T is `String`, data must be `ImmutableString`, so map directly to it diff --git a/src/lib.rs b/src/lib.rs index 98438971..883fe258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,8 +68,6 @@ extern crate no_std_compat as std; use std::prelude::v1::*; // Internal modules -mod reify; - mod api; mod ast; mod engine; @@ -79,6 +77,7 @@ mod module; mod optimizer; pub mod packages; mod parser; +mod reify; mod tests; mod tokenizer; mod types; diff --git a/src/reify.rs b/src/reify.rs index 82d3bdbe..acb65579 100644 --- a/src/reify.rs +++ b/src/reify.rs @@ -1,13 +1,16 @@ /// Runs `$code` if `$old` is of type `$t`. +/// +/// This macro is primarily used for type casting between known types. #[macro_export] macro_rules! reify { ($old:ident, |$new:ident : $t:ty| $code:expr, || $fallback:expr) => {{ #[allow(unused_imports)] - use ::std::{any::{Any, TypeId}, mem::{ManuallyDrop, transmute_copy}}; - if TypeId::of::<$t>() == $old.type_id() { + use std::any::Any; + + if std::any::TypeId::of::<$t>() == $old.type_id() { // SAFETY: This is safe because we check to make sure the two types are // actually the same type. - let $new: $t = unsafe { transmute_copy(&ManuallyDrop::new($old)) }; + let $new: $t = unsafe { std::mem::transmute_copy(&std::mem::ManuallyDrop::new($old)) }; $code } else { $fallback @@ -15,12 +18,29 @@ macro_rules! reify { }}; ($old:expr, |$new:ident : $t:ty| $code:expr, || $fallback:expr) => {{ let old = $old; - reify!(old, |$new : $t| $code, || $fallback) + reify!(old, |$new: $t| $code, || $fallback) }}; ($old:ident, |$new:ident : $t:ty| $code:expr) => { - reify!($old, |$new : $t| $code, || ()) + reify!($old, |$new: $t| $code, || ()) }; ($old:expr, |$new:ident : $t:ty| $code:expr) => { - reify!($old, |$new : $t| $code, || ()) + reify!($old, |$new: $t| $code, || ()) }; } + +#[macro_export] +macro_rules! reify_dynamic { + ($old:ident, |$new:ident : $t:ty| $code:expr) => {{ + #[allow(unused_imports)] + use ::std::{ + any::{Any, TypeId}, + mem::{transmute_copy, ManuallyDrop}, + }; + if TypeId::of::<$t>() == TypeId::of::() { + // SAFETY: This is safe because we check to make sure the two types are + // actually the same type. + let $new: $t = unsafe { transmute_copy(&ManuallyDrop::new($old)) }; + $code + } + }}; +} diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 489e4884..651c0c81 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -1,7 +1,7 @@ //! Helper module which defines the [`Any`] trait to to allow dynamic value handling. use crate::func::native::SendSync; -use crate::{ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT, reify}; +use crate::{reify, reify_dynamic, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{ @@ -1182,10 +1182,10 @@ impl Dynamic { reify!(value, |v: bool| return v.into()); reify!(value, |v: char| return v.into()); reify!(value, |v: ImmutableString| return v.into()); + reify!(value, |v: String| return v.into()); reify!(value, |v: &str| return v.into()); reify!(value, |v: ()| return v.into()); - reify!(value, |v: String| return v.into()); #[cfg(not(feature = "no_index"))] reify!(value, |v: crate::Array| return v.into()); #[cfg(not(feature = "no_index"))] @@ -1200,7 +1200,8 @@ impl Dynamic { #[cfg(not(feature = "no_std"))] reify!(value, |v: Instant| return v.into()); #[cfg(not(feature = "no_closure"))] - reify!(value, |v: crate::Shared>| return v.into()); + reify!(value, |v: crate::Shared>| return v + .into()); Self(Union::Variant( Box::new(Box::new(value)), @@ -1269,20 +1270,20 @@ impl Dynamic { return self.flatten().try_cast::(); } - reify!(self, |v: T| return Some(v)); + reify_dynamic!(self, |v: T| return Some(v)); match self.0 { Union::Int(v, ..) => reify!(v, |v: T| Some(v), || None), #[cfg(not(feature = "no_float"))] - Union::Float(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Float(v, ..) => reify!(*v, |v: T| Some(v), || None), #[cfg(feature = "decimal")] - Union::Decimal(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Decimal(v, ..) => reify!(*v, |v: T| Some(v), || None), Union::Bool(v, ..) => reify!(v, |v: T| Some(v), || None), Union::Str(v, ..) => { reify!(v, |v: T| Some(v), || { reify!(v.to_string(), |v: T| Some(v), || None) }) - }, + } Union::Char(v, ..) => reify!(v, |v: T| Some(v), || None), #[cfg(not(feature = "no_index"))] Union::Array(v, ..) => reify!(v, |v: Box| Some(*v), || None), @@ -1293,7 +1294,7 @@ impl Dynamic { Union::FnPtr(v, ..) => reify!(v, |v: Box| Some(*v), || None), #[cfg(not(feature = "no_std"))] Union::TimeStamp(v, ..) => reify!(v, |v: Box| Some(*v), || None), - Union::Unit(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Unit(_, ..) => reify!((), |v: T| Some(v), || None), Union::Variant(v, _, _) => (*v).as_boxed_any().downcast().ok().map(|x| *x), #[cfg(not(feature = "no_closure"))] Union::Shared(_, _, _) => unreachable!("Union::Shared case should be already handled"), @@ -1335,13 +1336,8 @@ impl Dynamic { #[cfg(feature = "no_closure")] let self_type_name = self.type_name(); - self.try_cast::().unwrap_or_else(|| { - panic!( - "cannot cast {} value and to {}", - self_type_name, - type_name::() - ) - }) + self.try_cast::() + .unwrap_or_else(|| panic!("cannot cast {} to {}", self_type_name, type_name::())) } /// Clone the [`Dynamic`] value and convert it into a specific type. /// From bd9519e96b2d0244f6859457e762f33cbf925700 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 7 Feb 2022 12:02:00 +0800 Subject: [PATCH 04/12] Remove reify_dynamic. --- src/reify.rs | 19 +------------------ src/types/dynamic.rs | 4 ++-- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/reify.rs b/src/reify.rs index acb65579..e0ac8481 100644 --- a/src/reify.rs +++ b/src/reify.rs @@ -7,7 +7,7 @@ macro_rules! reify { #[allow(unused_imports)] use std::any::Any; - if std::any::TypeId::of::<$t>() == $old.type_id() { + if std::any::TypeId::of::<$t>() == std::any::Any::type_id(&$old) { // SAFETY: This is safe because we check to make sure the two types are // actually the same type. let $new: $t = unsafe { std::mem::transmute_copy(&std::mem::ManuallyDrop::new($old)) }; @@ -27,20 +27,3 @@ macro_rules! reify { reify!($old, |$new: $t| $code, || ()) }; } - -#[macro_export] -macro_rules! reify_dynamic { - ($old:ident, |$new:ident : $t:ty| $code:expr) => {{ - #[allow(unused_imports)] - use ::std::{ - any::{Any, TypeId}, - mem::{transmute_copy, ManuallyDrop}, - }; - if TypeId::of::<$t>() == TypeId::of::() { - // SAFETY: This is safe because we check to make sure the two types are - // actually the same type. - let $new: $t = unsafe { transmute_copy(&ManuallyDrop::new($old)) }; - $code - } - }}; -} diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 651c0c81..ac2b85aa 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -1,7 +1,7 @@ //! Helper module which defines the [`Any`] trait to to allow dynamic value handling. use crate::func::native::SendSync; -use crate::{reify, reify_dynamic, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; +use crate::{reify, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, INT}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{ @@ -1270,7 +1270,7 @@ impl Dynamic { return self.flatten().try_cast::(); } - reify_dynamic!(self, |v: T| return Some(v)); + reify!(self, |v: T| return Some(v)); match self.0 { Union::Int(v, ..) => reify!(v, |v: T| Some(v), || None), From 556b2393f52d3f2e22d3a60c1e770537eef0801e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 7 Feb 2022 16:02:49 +0800 Subject: [PATCH 05/12] Fix position of function calls. --- src/bin/rhai-dbg.rs | 2 +- src/eval/expr.rs | 4 ++-- src/eval/stmt.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bin/rhai-dbg.rs b/src/bin/rhai-dbg.rs index 5158eebb..7e62e34c 100644 --- a/src/bin/rhai-dbg.rs +++ b/src/bin/rhai-dbg.rs @@ -271,7 +271,7 @@ fn main() { } DebuggerEvent::FunctionExitWithValue(r) => { println!( - "! Return from function call '{}' => {}", + "! Return from function call '{}' => {:?}", context .global_runtime_state() .debugger diff --git a/src/eval/expr.rs b/src/eval/expr.rs index b7e89972..67bc06b8 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -270,7 +270,7 @@ impl Engine { // Function calls should account for a relatively larger portion of expressions because // binary operators are also function calls. - if let Expr::FnCall(x, pos) = expr { + if let Expr::FnCall(x, _) = expr { #[cfg(feature = "debugging")] let reset_debugger = self.run_debugger_with_reset(scope, global, state, lib, this_ptr, expr, level)?; @@ -279,7 +279,7 @@ impl Engine { self.inc_operations(&mut global.num_operations, expr.position())?; let result = - self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, *pos, level); + self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, x.pos, level); #[cfg(feature = "debugging")] global.debugger.reset_status(reset_debugger); diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 1c4a06dc..9c43ea42 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -211,12 +211,12 @@ impl Engine { // Popular branches are lifted out of the `match` statement into their own branches. // Function calls should account for a relatively larger portion of statements. - if let Stmt::FnCall(x, pos) = stmt { + if let Stmt::FnCall(x, _) = stmt { #[cfg(not(feature = "unchecked"))] self.inc_operations(&mut global.num_operations, stmt.position())?; let result = - self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, *pos, level); + self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, x.pos, level); #[cfg(feature = "debugging")] global.debugger.reset_status(reset_debugger); From 187a20fd8b8c669f774d832e4b106b4da77f4aef Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 7 Feb 2022 21:03:39 +0800 Subject: [PATCH 06/12] Refactor OptimizationLevel. --- src/api/compile.rs | 24 +++++++----------------- src/api/eval.rs | 9 ++++++--- src/api/run.rs | 1 - src/bin/rhai-run.rs | 5 +---- src/engine.rs | 9 ++++----- src/eval/data_check.rs | 2 +- src/func/call.rs | 7 +++++-- src/lib.rs | 4 ++++ src/parser.rs | 9 ++++++--- 9 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/api/compile.rs b/src/api/compile.rs index d10ede04..9908e4b9 100644 --- a/src/api/compile.rs +++ b/src/api/compile.rs @@ -1,7 +1,7 @@ //! Module that defines the public compilation API of [`Engine`]. use crate::parser::{ParseResult, ParseState}; -use crate::{Engine, Scope, AST}; +use crate::{Engine, OptimizationLevel, Scope, AST}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -196,12 +196,7 @@ impl Engine { scope: &Scope, scripts: impl AsRef<[S]>, ) -> ParseResult { - self.compile_with_scope_and_optimization_level( - scope, - scripts, - #[cfg(not(feature = "no_optimize"))] - self.optimization_level, - ) + self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level) } /// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level. /// @@ -215,7 +210,7 @@ impl Engine { &self, scope: &Scope, scripts: impl AsRef<[S]>, - #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, + optimization_level: OptimizationLevel, ) -> ParseResult { let (stream, tokenizer_control) = self.lex_raw( scripts.as_ref(), @@ -226,7 +221,6 @@ impl Engine { &mut stream.peekable(), &mut state, scope, - #[cfg(not(feature = "no_optimize"))] optimization_level, ) } @@ -298,13 +292,7 @@ impl Engine { let mut peekable = stream.peekable(); let mut state = ParseState::new(self, tokenizer_control); - self.parse_global_expr( - &mut peekable, - &mut state, - scope, - #[cfg(not(feature = "no_optimize"))] - self.optimization_level, - ) + self.parse_global_expr(&mut peekable, &mut state, scope, self.optimization_level) } /// Parse a JSON string into an [object map][crate::Map]. /// This is a light-weight alternative to using, say, @@ -400,7 +388,9 @@ impl Engine { &mut state, &scope, #[cfg(not(feature = "no_optimize"))] - crate::OptimizationLevel::None, + OptimizationLevel::None, + #[cfg(feature = "no_optimize")] + OptimizationLevel::default(), )?; if has_null { scope.push_constant("null", ()); diff --git a/src/api/eval.rs b/src/api/eval.rs index 7e6eb83c..ff5c7254 100644 --- a/src/api/eval.rs +++ b/src/api/eval.rs @@ -3,7 +3,9 @@ use crate::eval::{EvalState, GlobalRuntimeState}; use crate::parser::ParseState; use crate::types::dynamic::Variant; -use crate::{Dynamic, Engine, Module, Position, RhaiResult, RhaiResultOf, Scope, AST, ERR}; +use crate::{ + Dynamic, Engine, Module, OptimizationLevel, Position, RhaiResult, RhaiResultOf, Scope, AST, ERR, +}; use std::any::type_name; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -64,7 +66,6 @@ impl Engine { let ast = self.compile_with_scope_and_optimization_level( scope, &[script], - #[cfg(not(feature = "no_optimize"))] self.optimization_level, )?; self.eval_ast_with_scope(scope, &ast) @@ -122,7 +123,9 @@ impl Engine { &mut state, scope, #[cfg(not(feature = "no_optimize"))] - crate::OptimizationLevel::None, + OptimizationLevel::None, + #[cfg(feature = "no_optimize")] + OptimizationLevel::default(), )?; self.eval_ast_with_scope(scope, &ast) diff --git a/src/api/run.rs b/src/api/run.rs index 7c556064..bad510a7 100644 --- a/src/api/run.rs +++ b/src/api/run.rs @@ -30,7 +30,6 @@ impl Engine { &mut stream.peekable(), &mut state, scope, - #[cfg(not(feature = "no_optimize"))] self.optimization_level, )?; diff --git a/src/bin/rhai-run.rs b/src/bin/rhai-run.rs index 567d4b45..257a7b08 100644 --- a/src/bin/rhai-run.rs +++ b/src/bin/rhai-run.rs @@ -1,8 +1,5 @@ use rhai::{Engine, EvalAltResult, Position}; -#[cfg(not(feature = "no_optimize"))] -use rhai::OptimizationLevel; - use std::{env, fs::File, io::Read, path::Path, process::exit}; fn eprint_error(input: &str, mut err: EvalAltResult) { @@ -53,7 +50,7 @@ fn main() { let mut engine = Engine::new(); #[cfg(not(feature = "no_optimize"))] - engine.set_optimization_level(OptimizationLevel::Full); + engine.set_optimization_level(rhai::OptimizationLevel::Full); let mut f = match File::open(&filename) { Err(err) => { diff --git a/src/engine.rs b/src/engine.rs index 86fb6859..e281c77c 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -8,7 +8,8 @@ use crate::packages::{Package, StandardPackage}; use crate::tokenizer::Token; use crate::types::dynamic::Union; use crate::{ - Dynamic, Identifier, ImmutableString, Module, Position, RhaiResult, Shared, StaticVec, + Dynamic, Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiResult, Shared, + StaticVec, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -131,8 +132,7 @@ pub struct Engine { pub(crate) progress: Option>, /// Optimize the [`AST`][crate::AST] after compilation. - #[cfg(not(feature = "no_optimize"))] - pub(crate) optimization_level: crate::OptimizationLevel, + pub(crate) optimization_level: OptimizationLevel, /// Language options. pub(crate) options: crate::api::options::LanguageOptions, @@ -287,8 +287,7 @@ impl Engine { #[cfg(not(feature = "unchecked"))] progress: None, - #[cfg(not(feature = "no_optimize"))] - optimization_level: crate::OptimizationLevel::default(), + optimization_level: OptimizationLevel::default(), options: crate::api::options::LanguageOptions::new(), diff --git a/src/eval/data_check.rs b/src/eval/data_check.rs index 4d5e1f78..c09197d2 100644 --- a/src/eval/data_check.rs +++ b/src/eval/data_check.rs @@ -10,7 +10,7 @@ use std::prelude::v1::*; impl Engine { /// Recursively calculate the sizes of a value. /// - /// Sizes returned are `(`[`Array`][crate::Array], [`Map`][crate::Map] and `String)`. + /// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`. /// /// # Panics /// diff --git a/src/func/call.rs b/src/func/call.rs index e688178a..fdd6c932 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -12,7 +12,8 @@ use crate::engine::{ use crate::eval::{EvalState, GlobalRuntimeState}; use crate::{ calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnArgsVec, FnPtr, - Identifier, ImmutableString, Module, Position, RhaiResult, RhaiResultOf, Scope, ERR, + Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiResult, RhaiResultOf, + Scope, ERR, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -1450,7 +1451,9 @@ impl Engine { &Scope::new(), &[script], #[cfg(not(feature = "no_optimize"))] - crate::OptimizationLevel::None, + OptimizationLevel::None, + #[cfg(feature = "no_optimize")] + OptimizationLevel::default(), )?; // If new functions are defined within the eval string, it is an error diff --git a/src/lib.rs b/src/lib.rs index 883fe258..18061326 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,6 +233,10 @@ pub mod serde; #[cfg(not(feature = "no_optimize"))] pub use optimizer::OptimizationLevel; +/// Placeholder for the optimization level. +#[cfg(feature = "no_optimize")] +pub type OptimizationLevel = (); + // Expose internal data structures. #[cfg(feature = "internals")] diff --git a/src/parser.rs b/src/parser.rs index ad02c52c..c7346f05 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -16,7 +16,7 @@ use crate::types::dynamic::AccessMode; use crate::types::StringsInterner; use crate::{ calc_fn_hash, Dynamic, Engine, ExclusiveRange, Identifier, ImmutableString, InclusiveRange, - LexError, ParseError, Position, Scope, Shared, StaticVec, AST, INT, PERR, + LexError, OptimizationLevel, ParseError, Position, Scope, Shared, StaticVec, AST, INT, PERR, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -3387,9 +3387,10 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, scope: &Scope, - #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, + optimization_level: OptimizationLevel, ) -> ParseResult { let _scope = scope; + let _optimization_level = optimization_level; let mut functions = BTreeMap::new(); let settings = ParseSettings { @@ -3517,9 +3518,11 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, scope: &Scope, - #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, + optimization_level: OptimizationLevel, ) -> ParseResult { let _scope = scope; + let _optimization_level = optimization_level; + let (statements, _lib) = self.parse_global_level(input, state)?; #[cfg(not(feature = "no_optimize"))] From f8cee0fe4e639334c0e06b7820a5bf808673bbff Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 09:02:15 +0800 Subject: [PATCH 07/12] Simplify using .. --- Cargo.toml | 2 +- codegen/src/function.rs | 14 +- codegen/src/module.rs | 16 +- codegen/src/rhai_module.rs | 4 +- src/api/compile.rs | 2 +- src/api/custom_syntax.rs | 18 +- src/ast/ast.rs | 10 +- src/ast/expr.rs | 270 +++++++++---------- src/ast/stmt.rs | 169 ++++++------ src/bin/rhai-dbg.rs | 2 +- src/bin/rhai-repl.rs | 4 +- src/engine.rs | 2 +- src/eval/chaining.rs | 90 ++++--- src/eval/data_check.rs | 28 +- src/eval/debugger.rs | 30 +-- src/eval/expr.rs | 34 +-- src/eval/stmt.rs | 72 +++--- src/func/call.rs | 32 +-- src/func/native.rs | 2 +- src/func/script.rs | 8 +- src/module/mod.rs | 8 +- src/module/resolvers/collection.rs | 2 +- src/module/resolvers/file.rs | 6 +- src/optimizer.rs | 168 ++++++------ src/packages/array_basic.rs | 41 +-- src/packages/blob_basic.rs | 6 +- src/packages/lang_core.rs | 8 +- src/parser.rs | 362 +++++++++++++------------- src/serde/de.rs | 54 ++-- src/serde/serialize.rs | 36 +-- src/tokenizer.rs | 84 +++--- src/types/dynamic.rs | 398 ++++++++++++++--------------- src/types/error.rs | 252 +++++++++--------- src/types/parse_error.rs | 2 +- src/types/scope.rs | 20 +- tests/call_fn.rs | 2 +- tests/closures.rs | 2 +- tests/constants.rs | 10 +- tests/custom_syntax.rs | 2 +- tests/data_size.rs | 26 +- tests/eval.rs | 2 +- tests/fn_ptr.rs | 2 +- tests/functions.rs | 8 +- tests/internal_fn.rs | 2 +- tests/maps.rs | 4 +- tests/math.rs | 22 +- tests/mismatched_op.rs | 8 +- tests/modules.rs | 8 +- tests/operations.rs | 4 +- tests/ops.rs | 4 +- tests/plugins.rs | 2 +- tests/string.rs | 2 +- tests/throw.rs | 6 +- tests/var_scope.rs | 2 +- 54 files changed, 1184 insertions(+), 1190 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c702f73f..19fcad41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,9 +50,9 @@ no_object = [] # no custom objects no_function = ["no_closure"] # no script-defined functions (meaning no closures) no_closure = [] # no automatic sharing and capture of anonymous functions to external variables no_module = [] # no modules -internals = [] # expose internal data structures unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers. metadata = ["serde", "serde_json", "rhai_codegen/metadata", "smartstring/serde"] # enable exporting functions metadata +internals = [] # expose internal data structures debugging = ["internals"] # enable debugging # compiling for no-std diff --git a/codegen/src/function.rs b/codegen/src/function.rs index 59f4f5ce..f0b14fd3 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -252,7 +252,7 @@ impl ExportedParams for ExportedFnParams { } } - (attr, _) => { + (attr, ..) => { return Err(syn::Error::new( key.span(), format!("unknown attribute '{}'", attr), @@ -379,7 +379,7 @@ impl Parse for ExportedFn { // Check return type. match fn_all.sig.output { - syn::ReturnType::Type(_, ref ret_type) => { + syn::ReturnType::Type(.., ref ret_type) => { match flatten_type_groups(ret_type.as_ref()) { syn::Type::Ptr(_) => { return Err(syn::Error::new( @@ -425,10 +425,10 @@ impl ExportedFn { pub fn update_scope(&mut self, parent_scope: &ExportScope) { let keep = match (self.params.skip, parent_scope) { - (true, _) => false, - (_, ExportScope::PubOnly) => self.is_public(), - (_, ExportScope::Prefix(s)) => self.name().to_string().starts_with(s), - (_, ExportScope::All) => true, + (true, ..) => false, + (.., ExportScope::PubOnly) => self.is_public(), + (.., ExportScope::Prefix(s)) => self.name().to_string().starts_with(s), + (.., ExportScope::All) => true, }; self.params.skip = !keep; } @@ -502,7 +502,7 @@ impl ExportedFn { pub fn return_type(&self) -> Option<&syn::Type> { match self.signature.output { - syn::ReturnType::Type(_, ref ret_type) => Some(flatten_type_groups(ret_type)), + syn::ReturnType::Type(.., ref ret_type) => Some(flatten_type_groups(ret_type)), _ => None, } } diff --git a/codegen/src/module.rs b/codegen/src/module.rs index 2a071ffc..6942b69c 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -69,7 +69,7 @@ impl ExportedParams for ExportedModParams { ("export_all", Some(s)) => { return Err(syn::Error::new(s.span(), "extraneous value")) } - (attr, _) => { + (attr, ..) => { return Err(syn::Error::new( key.span(), format!("unknown attribute '{}'", attr), @@ -109,7 +109,7 @@ impl Parse for Module { let mut consts = Vec::new(); let mut sub_modules = Vec::new(); - if let Some((_, ref mut content)) = mod_all.content { + if let Some((.., ref mut content)) = mod_all.content { // Gather and parse functions. fns = content .iter_mut() @@ -211,10 +211,10 @@ impl Module { pub fn update_scope(&mut self, parent_scope: &ExportScope) { let keep = match (self.params.skip, parent_scope) { - (true, _) => false, - (_, ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(_)), - (_, ExportScope::Prefix(s)) => self.mod_all.ident.to_string().starts_with(s), - (_, ExportScope::All) => true, + (true, ..) => false, + (.., ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(_)), + (.., ExportScope::Prefix(s)) => self.mod_all.ident.to_string().starts_with(s), + (.., ExportScope::All) => true, }; self.params.skip = !keep; } @@ -245,7 +245,7 @@ impl Module { } = self; let mod_vis = mod_all.vis; let mod_name = mod_all.ident.clone(); - let (_, orig_content) = mod_all.content.take().unwrap(); + let (.., orig_content) = mod_all.content.take().unwrap(); let mod_attrs = mem::take(&mut mod_all.attrs); if !params.skip { @@ -312,7 +312,7 @@ impl Module { pub fn content(&self) -> Option<&[syn::Item]> { match self.mod_all { syn::ItemMod { - content: Some((_, ref vec)), + content: Some((.., ref vec)), .. } => Some(vec), _ => None, diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index b922c231..eda915f2 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -240,7 +240,7 @@ pub fn generate_body( }) .unwrap(); - let (_, generate_call_content) = generate_fn_call.content.take().unwrap(); + let (.., generate_call_content) = generate_fn_call.content.take().unwrap(); quote! { #(#generate_call_content)* @@ -275,7 +275,7 @@ pub fn check_rename_collisions(fns: &[ExportedFn]) -> Result<(), syn::Error> { .map(|n| (n.clone(), n.clone())) .collect(); - if let Some((s, n, _)) = item_fn.params().special.get_fn_name() { + if let Some((s, n, ..)) = item_fn.params().special.get_fn_name() { names.push((s, n)); } diff --git a/src/api/compile.rs b/src/api/compile.rs index 9908e4b9..39595a8d 100644 --- a/src/api/compile.rs +++ b/src/api/compile.rs @@ -99,7 +99,7 @@ impl Engine { ) { ast.walk(&mut |path| match path.last().unwrap() { // Collect all `import` statements with a string constant path - ASTNode::Stmt(Stmt::Import(Expr::StringConstant(s, _), _, _)) + ASTNode::Stmt(Stmt::Import(Expr::StringConstant(s, ..), ..)) if !resolver.contains_path(s) && !imports.contains(s.as_str()) => { imports.insert(s.clone().into()); diff --git a/src/api/custom_syntax.rs b/src/api/custom_syntax.rs index 5e6232b6..c0f15ff4 100644 --- a/src/api/custom_syntax.rs +++ b/src/api/custom_syntax.rs @@ -72,9 +72,9 @@ impl Expression<'_> { pub fn get_string_value(&self) -> Option<&str> { match self.0 { #[cfg(not(feature = "no_module"))] - Expr::Variable(_, _, x) if x.1.is_some() => None, - Expr::Variable(_, _, x) => Some(x.2.as_str()), - Expr::StringConstant(x, _) => Some(x.as_str()), + Expr::Variable(.., _, x) if x.1.is_some() => None, + Expr::Variable(.., _, x) => Some(x.2.as_str()), + Expr::StringConstant(x, ..) => Some(x.as_str()), _ => None, } } @@ -94,18 +94,18 @@ impl Expression<'_> { pub fn get_literal_value(&self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. match self.0 { - Expr::IntegerConstant(x, _) => reify!(*x, |x: T| Some(x), || None), + Expr::IntegerConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(x, _) => reify!(*x, |x: T| Some(x), || None), + Expr::FloatConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), - Expr::CharConstant(x, _) => reify!(*x, |x: T| Some(x), || None), - Expr::StringConstant(x, _) => reify!(x.clone(), |x: T| Some(x), || None), - Expr::Variable(_, _, x) => { + Expr::CharConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), + Expr::StringConstant(x, ..) => reify!(x.clone(), |x: T| Some(x), || None), + Expr::Variable(.., _, x) => { let x: ImmutableString = x.2.clone().into(); reify!(x, |x: T| Some(x), || None) } - Expr::BoolConstant(x, _) => reify!(*x, |x: T| Some(x), || None), + Expr::BoolConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), Expr::Unit(_) => reify!((), |x: T| Some(x), || None), _ => None, diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 7077bad6..02ea8545 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -53,7 +53,7 @@ impl fmt::Debug for AST { #[cfg(not(feature = "no_function"))] if !self.lib.is_empty() { - for (_, _, _, _, ref fn_def) in self.lib.iter_script_fn() { + for (.., ref fn_def) in self.lib.iter_script_fn() { let sig = fn_def.to_string(); fp.field(&sig, &fn_def.body.as_slice()); } @@ -640,7 +640,7 @@ impl AST { pub fn iter_fn_def(&self) -> impl Iterator { self.lib .iter_script_fn() - .map(|(_, _, _, _, fn_def)| fn_def.as_ref()) + .map(|(.., fn_def)| fn_def.as_ref()) } /// Iterate through all function definitions. /// @@ -652,7 +652,7 @@ impl AST { pub(crate) fn iter_fn_def(&self) -> impl Iterator { self.lib .iter_script_fn() - .map(|(_, _, _, _, fn_def)| fn_def.as_ref()) + .map(|(.., fn_def)| fn_def.as_ref()) } /// Iterate through all function definitions. /// @@ -662,7 +662,7 @@ impl AST { pub fn iter_functions<'a>(&'a self) -> impl Iterator + 'a { self.lib .iter_script_fn() - .map(|(_, _, _, _, fn_def)| fn_def.as_ref().into()) + .map(|(.., fn_def)| fn_def.as_ref().into()) } /// Clear all function definitions in the [`AST`]. /// @@ -744,7 +744,7 @@ impl AST { include_variables: bool, ) -> impl Iterator { self.statements().iter().filter_map(move |stmt| match stmt { - Stmt::Var(expr, name, options, _) + Stmt::Var(expr, name, options, ..) if options.contains(AST_OPTION_CONSTANT) && include_constants || !options.contains(AST_OPTION_CONSTANT) && include_variables => { diff --git a/src/ast/expr.rs b/src/ast/expr.rs index dffacf42..75d23e9a 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -443,24 +443,24 @@ impl fmt::Debug for Expr { let mut display_pos = self.start_position(); match self { - Self::DynamicConstant(value, _) => write!(f, "{:?}", value), - Self::BoolConstant(value, _) => write!(f, "{:?}", value), - Self::IntegerConstant(value, _) => write!(f, "{:?}", value), + Self::DynamicConstant(value, ..) => write!(f, "{:?}", value), + Self::BoolConstant(value, ..) => write!(f, "{:?}", value), + Self::IntegerConstant(value, ..) => write!(f, "{:?}", value), #[cfg(not(feature = "no_float"))] - Self::FloatConstant(value, _) => write!(f, "{:?}", value), - Self::CharConstant(value, _) => write!(f, "{:?}", value), - Self::StringConstant(value, _) => write!(f, "{:?}", value), + Self::FloatConstant(value, ..) => write!(f, "{:?}", value), + Self::CharConstant(value, ..) => write!(f, "{:?}", value), + Self::StringConstant(value, ..) => write!(f, "{:?}", value), Self::Unit(_) => f.write_str("()"), - Self::InterpolatedString(x, _) => { + Self::InterpolatedString(x, ..) => { f.write_str("InterpolatedString")?; return f.debug_list().entries(x.iter()).finish(); } - Self::Array(x, _) => { + Self::Array(x, ..) => { f.write_str("Array")?; f.debug_list().entries(x.iter()).finish() } - Self::Map(x, _) => { + Self::Map(x, ..) => { f.write_str("Map")?; f.debug_map() .entries(x.0.iter().map(|(k, v)| (k, v))) @@ -470,7 +470,7 @@ impl fmt::Debug for Expr { f.write_str("Variable(")?; #[cfg(not(feature = "no_module"))] - if let Some((_, ref namespace)) = x.1 { + if let Some((.., ref namespace)) = x.1 { write!(f, "{}{}", namespace, Token::DoubleColon.literal_syntax())? } f.write_str(&x.2)?; @@ -479,13 +479,13 @@ impl fmt::Debug for Expr { } f.write_str(")") } - Self::Property(x, _) => write!(f, "Property({})", x.2), - Self::Stack(x, _) => write!(f, "ConstantArg#{}", x), + Self::Property(x, ..) => write!(f, "Property({})", x.2), + Self::Stack(x, ..) => write!(f, "ConstantArg#{}", x), Self::Stmt(x) => { f.write_str("ExprStmtBlock")?; f.debug_list().entries(x.iter()).finish() } - Self::FnCall(x, _) => fmt::Debug::fmt(x, f), + Self::FnCall(x, ..) => fmt::Debug::fmt(x, f), Self::Index(x, term, pos) => { display_pos = *pos; @@ -497,9 +497,9 @@ impl fmt::Debug for Expr { } Self::Dot(x, _, pos) | Self::And(x, pos) | Self::Or(x, pos) => { let op_name = match self { - Self::Dot(_, _, _) => "Dot", - Self::And(_, _) => "And", - Self::Or(_, _) => "Or", + Self::Dot(..) => "Dot", + Self::And(..) => "And", + Self::Or(..) => "Or", expr => unreachable!( "Self::Dot or Self::And or Self::Or expected but gets {:?}", expr @@ -513,7 +513,7 @@ impl fmt::Debug for Expr { .field("rhs", &x.rhs) .finish() } - Self::Custom(x, _) => f.debug_tuple("Custom").field(x).finish(), + Self::Custom(x, ..) => f.debug_tuple("Custom").field(x).finish(), }?; display_pos.debug_print(f) @@ -528,24 +528,24 @@ impl Expr { #[must_use] pub fn get_literal_value(&self) -> Option { Some(match self { - Self::DynamicConstant(x, _) => x.as_ref().clone(), - Self::IntegerConstant(x, _) => (*x).into(), + Self::DynamicConstant(x, ..) => x.as_ref().clone(), + Self::IntegerConstant(x, ..) => (*x).into(), #[cfg(not(feature = "no_float"))] - Self::FloatConstant(x, _) => (*x).into(), - Self::CharConstant(x, _) => (*x).into(), - Self::StringConstant(x, _) => x.clone().into(), - Self::BoolConstant(x, _) => (*x).into(), + Self::FloatConstant(x, ..) => (*x).into(), + Self::CharConstant(x, ..) => (*x).into(), + Self::StringConstant(x, ..) => x.clone().into(), + Self::BoolConstant(x, ..) => (*x).into(), Self::Unit(_) => Dynamic::UNIT, #[cfg(not(feature = "no_index"))] - Self::Array(x, _) if self.is_constant() => { + Self::Array(x, ..) if self.is_constant() => { let mut arr = crate::Array::with_capacity(x.len()); arr.extend(x.iter().map(|v| v.get_literal_value().unwrap())); Dynamic::from_array(arr) } #[cfg(not(feature = "no_object"))] - Self::Map(x, _) if self.is_constant() => { + Self::Map(x, ..) if self.is_constant() => { Dynamic::from_map(x.0.iter().fold(x.1.clone(), |mut map, (k, v)| { let value_ref = map.get_mut(k.name.as_str()).unwrap(); *value_ref = v.get_literal_value().unwrap(); @@ -554,10 +554,10 @@ impl Expr { } // Fn - Self::FnCall(ref x, _) + Self::FnCall(ref x, ..) if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR => { - if let Expr::StringConstant(ref s, _) = x.args[0] { + if let Expr::StringConstant(ref s, ..) = x.args[0] { if let Ok(fn_ptr) = FnPtr::new(s) { fn_ptr.into() } else { @@ -569,33 +569,35 @@ impl Expr { } // Binary operators - Self::FnCall(x, _) if !x.is_qualified() && x.args.len() == 2 => match x.name.as_str() { - // x..y - OP_EXCLUSIVE_RANGE => { - if let Expr::IntegerConstant(ref start, _) = x.args[0] { - if let Expr::IntegerConstant(ref end, _) = x.args[1] { - (*start..*end).into() + Self::FnCall(x, ..) if !x.is_qualified() && x.args.len() == 2 => { + match x.name.as_str() { + // x..y + OP_EXCLUSIVE_RANGE => { + if let Expr::IntegerConstant(ref start, ..) = x.args[0] { + if let Expr::IntegerConstant(ref end, ..) = x.args[1] { + (*start..*end).into() + } else { + return None; + } } else { return None; } - } else { - return None; } - } - // x..=y - OP_INCLUSIVE_RANGE => { - if let Expr::IntegerConstant(ref start, _) = x.args[0] { - if let Expr::IntegerConstant(ref end, _) = x.args[1] { - (*start..=*end).into() + // x..=y + OP_INCLUSIVE_RANGE => { + if let Expr::IntegerConstant(ref start, ..) = x.args[0] { + if let Expr::IntegerConstant(ref end, ..) = x.args[1] { + (*start..=*end).into() + } else { + return None; + } } else { return None; } - } else { - return None; } + _ => return None, } - _ => return None, - }, + } _ => return None, }) @@ -605,25 +607,25 @@ impl Expr { #[must_use] pub fn from_dynamic(value: Dynamic, pos: Position) -> Self { match value.0 { - Union::Unit(_, _, _) => Self::Unit(pos), - Union::Bool(b, _, _) => Self::BoolConstant(b, pos), - Union::Str(s, _, _) => Self::StringConstant(s, pos), - Union::Char(c, _, _) => Self::CharConstant(c, pos), - Union::Int(i, _, _) => Self::IntegerConstant(i, pos), + Union::Unit(..) => Self::Unit(pos), + Union::Bool(b, ..) => Self::BoolConstant(b, pos), + Union::Str(s, ..) => Self::StringConstant(s, pos), + Union::Char(c, ..) => Self::CharConstant(c, pos), + Union::Int(i, ..) => Self::IntegerConstant(i, pos), #[cfg(feature = "decimal")] - Union::Decimal(value, _, _) => Self::DynamicConstant(Box::new((*value).into()), pos), + Union::Decimal(value, ..) => Self::DynamicConstant(Box::new((*value).into()), pos), #[cfg(not(feature = "no_float"))] - Union::Float(f, _, _) => Self::FloatConstant(f, pos), + Union::Float(f, ..) => Self::FloatConstant(f, pos), #[cfg(not(feature = "no_index"))] - Union::Array(a, _, _) => Self::DynamicConstant(Box::new((*a).into()), pos), + Union::Array(a, ..) => Self::DynamicConstant(Box::new((*a).into()), pos), #[cfg(not(feature = "no_object"))] - Union::Map(m, _, _) => Self::DynamicConstant(Box::new((*m).into()), pos), + Union::Map(m, ..) => Self::DynamicConstant(Box::new((*m).into()), pos), - Union::FnPtr(f, _, _) if !f.is_curried() => Self::FnCall( + Union::FnPtr(f, ..) if !f.is_curried() => Self::FnCall( FnCallExpr { #[cfg(not(feature = "no_module"))] namespace: None, @@ -651,8 +653,8 @@ impl Expr { match self { #[cfg(not(feature = "no_module"))] - Self::Variable(_, _, x) if _non_qualified && x.1.is_some() => false, - Self::Variable(_, _, _) => true, + Self::Variable(.., x) if _non_qualified && x.1.is_some() => false, + Self::Variable(..) => true, _ => false, } } @@ -666,8 +668,8 @@ impl Expr { match self { #[cfg(not(feature = "no_module"))] - Self::Variable(_, _, x) if _non_qualified && x.1.is_some() => None, - Self::Variable(_, _, x) => Some(x.2.as_str()), + Self::Variable(.., x) if _non_qualified && x.1.is_some() => None, + Self::Variable(.., x) => Some(x.2.as_str()), _ => None, } } @@ -677,27 +679,27 @@ impl Expr { pub const fn position(&self) -> Position { match self { #[cfg(not(feature = "no_float"))] - Self::FloatConstant(_, pos) => *pos, + Self::FloatConstant(.., pos) => *pos, - Self::DynamicConstant(_, pos) - | Self::BoolConstant(_, pos) - | Self::IntegerConstant(_, pos) - | Self::CharConstant(_, pos) + Self::DynamicConstant(.., pos) + | Self::BoolConstant(.., pos) + | Self::IntegerConstant(.., pos) + | Self::CharConstant(.., pos) | Self::Unit(pos) - | Self::StringConstant(_, pos) - | Self::Array(_, pos) - | Self::Map(_, pos) - | Self::Variable(_, pos, _) - | Self::Stack(_, pos) - | Self::And(_, pos) - | Self::Or(_, pos) - | Self::Index(_, _, pos) - | Self::Dot(_, _, pos) - | Self::Custom(_, pos) - | Self::InterpolatedString(_, pos) - | Self::Property(_, pos) => *pos, + | Self::StringConstant(.., pos) + | Self::Array(.., pos) + | Self::Map(.., pos) + | Self::Variable(.., pos, _) + | Self::Stack(.., pos) + | Self::And(.., pos) + | Self::Or(.., pos) + | Self::Index(.., pos) + | Self::Dot(.., pos) + | Self::Custom(.., pos) + | Self::InterpolatedString(.., pos) + | Self::Property(.., pos) => *pos, - Self::FnCall(x, _) => x.pos, + Self::FnCall(x, ..) => x.pos, Self::Stmt(x) => x.position(), } @@ -708,10 +710,10 @@ impl Expr { #[must_use] pub const fn start_position(&self) -> Position { match self { - Self::And(x, _) | Self::Or(x, _) | Self::Index(x, _, _) | Self::Dot(x, _, _) => { + Self::And(x, ..) | Self::Or(x, ..) | Self::Index(x, ..) | Self::Dot(x, ..) => { x.lhs.start_position() } - Self::FnCall(_, pos) => *pos, + Self::FnCall(.., pos) => *pos, _ => self.position(), } } @@ -720,26 +722,26 @@ impl Expr { pub fn set_position(&mut self, new_pos: Position) -> &mut Self { match self { #[cfg(not(feature = "no_float"))] - Self::FloatConstant(_, pos) => *pos = new_pos, + Self::FloatConstant(.., pos) => *pos = new_pos, - Self::DynamicConstant(_, pos) - | Self::BoolConstant(_, pos) - | Self::IntegerConstant(_, pos) - | Self::CharConstant(_, pos) + Self::DynamicConstant(.., pos) + | Self::BoolConstant(.., pos) + | Self::IntegerConstant(.., pos) + | Self::CharConstant(.., pos) | Self::Unit(pos) - | Self::StringConstant(_, pos) - | Self::Array(_, pos) - | Self::Map(_, pos) - | Self::And(_, pos) - | Self::Or(_, pos) - | Self::Dot(_, _, pos) - | Self::Index(_, _, pos) - | Self::Variable(_, pos, _) - | Self::Stack(_, pos) - | Self::FnCall(_, pos) - | Self::Custom(_, pos) - | Self::InterpolatedString(_, pos) - | Self::Property(_, pos) => *pos = new_pos, + | Self::StringConstant(.., pos) + | Self::Array(.., pos) + | Self::Map(.., pos) + | Self::And(.., pos) + | Self::Or(.., pos) + | Self::Dot(.., pos) + | Self::Index(.., pos) + | Self::Variable(.., pos, _) + | Self::Stack(.., pos) + | Self::FnCall(.., pos) + | Self::Custom(.., pos) + | Self::InterpolatedString(.., pos) + | Self::Property(.., pos) => *pos = new_pos, Self::Stmt(x) => x.set_position(new_pos, Position::NONE), } @@ -753,15 +755,15 @@ impl Expr { #[must_use] pub fn is_pure(&self) -> bool { match self { - Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_pure), + Self::InterpolatedString(x, ..) | Self::Array(x, ..) => x.iter().all(Self::is_pure), - Self::Map(x, _) => x.0.iter().map(|(_, v)| v).all(Self::is_pure), + Self::Map(x, ..) => x.0.iter().map(|(.., v)| v).all(Self::is_pure), - Self::And(x, _) | Self::Or(x, _) => x.lhs.is_pure() && x.rhs.is_pure(), + Self::And(x, ..) | Self::Or(x, ..) => x.lhs.is_pure() && x.rhs.is_pure(), Self::Stmt(x) => x.iter().all(Stmt::is_pure), - Self::Variable(_, _, _) | Self::Stack(_, _) => true, + Self::Variable(..) | Self::Stack(..) => true, _ => self.is_constant(), } @@ -778,19 +780,19 @@ impl Expr { pub fn is_constant(&self) -> bool { match self { #[cfg(not(feature = "no_float"))] - Self::FloatConstant(_, _) => true, + Self::FloatConstant(..) => true, - Self::DynamicConstant(_, _) - | Self::BoolConstant(_, _) - | Self::IntegerConstant(_, _) - | Self::CharConstant(_, _) - | Self::StringConstant(_, _) + Self::DynamicConstant(..) + | Self::BoolConstant(..) + | Self::IntegerConstant(..) + | Self::CharConstant(..) + | Self::StringConstant(..) | Self::Unit(_) - | Self::Stack(_, _) => true, + | Self::Stack(..) => true, - Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_constant), + Self::InterpolatedString(x, ..) | Self::Array(x, ..) => x.iter().all(Self::is_constant), - Self::Map(x, _) => x.0.iter().map(|(_, expr)| expr).all(Self::is_constant), + Self::Map(x, ..) => x.0.iter().map(|(.., expr)| expr).all(Self::is_constant), _ => false, } @@ -807,31 +809,31 @@ impl Expr { match self { #[cfg(not(feature = "no_float"))] - Self::FloatConstant(_, _) => false, + Self::FloatConstant(..) => false, - Self::DynamicConstant(_, _) - | Self::BoolConstant(_, _) - | Self::CharConstant(_, _) - | Self::And(_, _) - | Self::Or(_, _) + Self::DynamicConstant(..) + | Self::BoolConstant(..) + | Self::CharConstant(..) + | Self::And(..) + | Self::Or(..) | Self::Unit(_) => false, - Self::IntegerConstant(_, _) - | Self::StringConstant(_, _) - | Self::InterpolatedString(_, _) - | Self::FnCall(_, _) + Self::IntegerConstant(..) + | Self::StringConstant(..) + | Self::InterpolatedString(..) + | Self::FnCall(..) | Self::Stmt(_) - | Self::Dot(_, _, _) - | Self::Index(_, _, _) - | Self::Array(_, _) - | Self::Map(_, _) - | Self::Custom(_, _) => match token { + | Self::Dot(..) + | Self::Index(..) + | Self::Array(..) + | Self::Map(..) + | Self::Custom(..) => match token { #[cfg(not(feature = "no_index"))] Token::LeftBracket => true, _ => false, }, - Self::Variable(_, _, _) => match token { + Self::Variable(..) => match token { #[cfg(not(feature = "no_index"))] Token::LeftBracket => true, Token::LeftParen => true, @@ -840,14 +842,14 @@ impl Expr { _ => false, }, - Self::Property(_, _) => match token { + Self::Property(..) => match token { #[cfg(not(feature = "no_index"))] Token::LeftBracket => true, Token::LeftParen => true, _ => false, }, - Self::Stack(_, _) => false, + Self::Stack(..) => false, } } /// Recursively walk this expression. @@ -872,21 +874,21 @@ impl Expr { } } } - Self::InterpolatedString(x, _) | Self::Array(x, _) => { + Self::InterpolatedString(x, ..) | Self::Array(x, ..) => { for e in x.as_ref() { if !e.walk(path, on_node) { return false; } } } - Self::Map(x, _) => { - for (_, e) in &x.0 { + Self::Map(x, ..) => { + for (.., e) in &x.0 { if !e.walk(path, on_node) { return false; } } } - Self::Index(x, _, _) | Self::Dot(x, _, _) | Expr::And(x, _) | Expr::Or(x, _) => { + Self::Index(x, ..) | Self::Dot(x, ..) | Expr::And(x, ..) | Expr::Or(x, ..) => { if !x.lhs.walk(path, on_node) { return false; } @@ -894,14 +896,14 @@ impl Expr { return false; } } - Self::FnCall(x, _) => { + Self::FnCall(x, ..) => { for e in &x.args { if !e.walk(path, on_node) { return false; } } } - Self::Custom(x, _) => { + Self::Custom(x, ..) => { for e in &x.inputs { if !e.walk(path, on_node) { return false; diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index ca82fb8f..c33f5913 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -411,25 +411,25 @@ impl Stmt { pub const fn position(&self) -> Position { match self { Self::Noop(pos) - | Self::BreakLoop(_, pos) - | Self::Block(_, (pos, _)) - | Self::Assignment(_, pos) - | Self::FnCall(_, pos) - | Self::If(_, _, pos) - | Self::Switch(_, _, pos) - | Self::While(_, _, pos) - | Self::Do(_, _, _, pos) - | Self::For(_, _, pos) - | Self::Return(_, _, pos) - | Self::Var(_, _, _, pos) - | Self::TryCatch(_, pos) => *pos, + | Self::BreakLoop(.., pos) + | Self::Block(.., (pos, ..)) + | Self::Assignment(.., pos) + | Self::FnCall(.., pos) + | Self::If(.., pos) + | Self::Switch(.., pos) + | Self::While(.., pos) + | Self::Do(.., pos) + | Self::For(.., pos) + | Self::Return(.., pos) + | Self::Var(.., pos) + | Self::TryCatch(.., pos) => *pos, Self::Expr(x) => x.start_position(), #[cfg(not(feature = "no_module"))] - Self::Import(_, _, pos) => *pos, + Self::Import(.., pos) => *pos, #[cfg(not(feature = "no_module"))] - Self::Export(_, pos) => *pos, + Self::Export(.., pos) => *pos, #[cfg(not(feature = "no_closure"))] Self::Share(_) => Position::NONE, @@ -439,27 +439,27 @@ impl Stmt { pub fn set_position(&mut self, new_pos: Position) -> &mut Self { match self { Self::Noop(pos) - | Self::BreakLoop(_, pos) - | Self::Block(_, (pos, _)) - | Self::Assignment(_, pos) - | Self::FnCall(_, pos) - | Self::If(_, _, pos) - | Self::Switch(_, _, pos) - | Self::While(_, _, pos) - | Self::Do(_, _, _, pos) - | Self::For(_, _, pos) - | Self::Return(_, _, pos) - | Self::Var(_, _, _, pos) - | Self::TryCatch(_, pos) => *pos = new_pos, + | Self::BreakLoop(.., pos) + | Self::Block(.., (pos, ..)) + | Self::Assignment(.., pos) + | Self::FnCall(.., pos) + | Self::If(.., pos) + | Self::Switch(.., pos) + | Self::While(.., pos) + | Self::Do(.., pos) + | Self::For(.., pos) + | Self::Return(.., pos) + | Self::Var(.., pos) + | Self::TryCatch(.., pos) => *pos = new_pos, Self::Expr(x) => { x.set_position(new_pos); } #[cfg(not(feature = "no_module"))] - Self::Import(_, _, pos) => *pos = new_pos, + Self::Import(.., pos) => *pos = new_pos, #[cfg(not(feature = "no_module"))] - Self::Export(_, pos) => *pos = new_pos, + Self::Export(.., pos) => *pos = new_pos, #[cfg(not(feature = "no_closure"))] Self::Share(_) => (), @@ -471,25 +471,20 @@ impl Stmt { #[must_use] pub const fn returns_value(&self) -> bool { match self { - Self::If(_, _, _) - | Self::Switch(_, _, _) - | Self::Block(_, _) + Self::If(..) + | Self::Switch(..) + | Self::Block(..) | Self::Expr(_) - | Self::FnCall(_, _) => true, + | Self::FnCall(..) => true, - Self::Noop(_) - | Self::While(_, _, _) - | Self::Do(_, _, _, _) - | Self::For(_, _, _) - | Self::TryCatch(_, _) => false, + Self::Noop(_) | Self::While(..) | Self::Do(..) | Self::For(..) | Self::TryCatch(..) => { + false + } - Self::Var(_, _, _, _) - | Self::Assignment(_, _) - | Self::BreakLoop(_, _) - | Self::Return(_, _, _) => false, + Self::Var(..) | Self::Assignment(..) | Self::BreakLoop(..) | Self::Return(..) => false, #[cfg(not(feature = "no_module"))] - Self::Import(_, _, _) | Self::Export(_, _) => false, + Self::Import(..) | Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] Self::Share(_) => false, @@ -499,28 +494,28 @@ impl Stmt { #[must_use] pub const fn is_self_terminated(&self) -> bool { match self { - Self::If(_, _, _) - | Self::Switch(_, _, _) - | Self::While(_, _, _) - | Self::For(_, _, _) - | Self::Block(_, _) - | Self::TryCatch(_, _) => true, + Self::If(..) + | Self::Switch(..) + | Self::While(..) + | Self::For(..) + | Self::Block(..) + | Self::TryCatch(..) => true, // A No-op requires a semicolon in order to know it is an empty statement! Self::Noop(_) => false, - Self::Expr(Expr::Custom(x, _)) if x.is_self_terminated() => true, + Self::Expr(Expr::Custom(x, ..)) if x.is_self_terminated() => true, - Self::Var(_, _, _, _) - | Self::Assignment(_, _) + Self::Var(..) + | Self::Assignment(..) | Self::Expr(_) - | Self::FnCall(_, _) - | Self::Do(_, _, _, _) - | Self::BreakLoop(_, _) - | Self::Return(_, _, _) => false, + | Self::FnCall(..) + | Self::Do(..) + | Self::BreakLoop(..) + | Self::Return(..) => false, #[cfg(not(feature = "no_module"))] - Self::Import(_, _, _) | Self::Export(_, _) => false, + Self::Import(..) | Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] Self::Share(_) => false, @@ -534,18 +529,18 @@ impl Stmt { match self { Self::Noop(_) => true, Self::Expr(expr) => expr.is_pure(), - Self::If(condition, x, _) => { + Self::If(condition, x, ..) => { condition.is_pure() && x.0.iter().all(Stmt::is_pure) && x.1.iter().all(Stmt::is_pure) } - Self::Switch(expr, x, _) => { + Self::Switch(expr, x, ..) => { expr.is_pure() && x.cases.values().all(|block| { block.condition.as_ref().map(Expr::is_pure).unwrap_or(true) && block.statements.iter().all(Stmt::is_pure) }) - && x.ranges.iter().all(|(_, _, _, block)| { + && x.ranges.iter().all(|(.., block)| { block.condition.as_ref().map(Expr::is_pure).unwrap_or(true) && block.statements.iter().all(Stmt::is_pure) }) @@ -553,31 +548,31 @@ impl Stmt { } // Loops that exit can be pure because it can never be infinite. - Self::While(Expr::BoolConstant(false, _), _, _) => true, - Self::Do(body, Expr::BoolConstant(x, _), options, _) + Self::While(Expr::BoolConstant(false, ..), ..) => true, + Self::Do(body, Expr::BoolConstant(x, ..), options, ..) if *x == options.contains(AST_OPTION_NEGATED) => { body.iter().all(Stmt::is_pure) } // Loops are never pure since they can be infinite - and that's a side effect. - Self::While(_, _, _) | Self::Do(_, _, _, _) => false, + Self::While(..) | Self::Do(..) => false, // For loops can be pure because if the iterable is pure, it is finite, // so infinite loops can never occur. - Self::For(iterable, x, _) => iterable.is_pure() && x.2.iter().all(Stmt::is_pure), + Self::For(iterable, x, ..) => iterable.is_pure() && x.2.iter().all(Stmt::is_pure), - Self::Var(_, _, _, _) | Self::Assignment(_, _) | Self::FnCall(_, _) => false, - Self::Block(block, _) => block.iter().all(|stmt| stmt.is_pure()), - Self::BreakLoop(_, _) | Self::Return(_, _, _) => false, - Self::TryCatch(x, _) => { + Self::Var(..) | Self::Assignment(..) | Self::FnCall(..) => false, + Self::Block(block, ..) => block.iter().all(|stmt| stmt.is_pure()), + Self::BreakLoop(..) | Self::Return(..) => false, + Self::TryCatch(x, ..) => { x.try_block.iter().all(Stmt::is_pure) && x.catch_block.iter().all(Stmt::is_pure) } #[cfg(not(feature = "no_module"))] - Self::Import(_, _, _) => false, + Self::Import(..) => false, #[cfg(not(feature = "no_module"))] - Self::Export(_, _) => false, + Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] Self::Share(_) => false, @@ -594,16 +589,16 @@ impl Stmt { #[must_use] pub fn is_block_dependent(&self) -> bool { match self { - Self::Var(_, _, _, _) => true, + Self::Var(..) => true, Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_block_dependent), - Self::FnCall(x, _) | Self::Expr(Expr::FnCall(x, _)) => { + Self::FnCall(x, ..) | Self::Expr(Expr::FnCall(x, ..)) => { !x.is_qualified() && x.name == KEYWORD_EVAL } #[cfg(not(feature = "no_module"))] - Self::Import(_, _, _) | Self::Export(_, _) => true, + Self::Import(..) | Self::Export(..) => true, _ => false, } @@ -618,14 +613,14 @@ impl Stmt { #[must_use] pub fn is_internally_pure(&self) -> bool { match self { - Self::Var(expr, _, _, _) => expr.is_pure(), + Self::Var(expr, _, ..) => expr.is_pure(), Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_internally_pure), #[cfg(not(feature = "no_module"))] - Self::Import(expr, _, _) => expr.is_pure(), + Self::Import(expr, ..) => expr.is_pure(), #[cfg(not(feature = "no_module"))] - Self::Export(_, _) => true, + Self::Export(..) => true, _ => self.is_pure(), } @@ -639,7 +634,7 @@ impl Stmt { #[must_use] pub const fn is_control_flow_break(&self) -> bool { match self { - Self::Return(_, _, _) | Self::BreakLoop(_, _) => true, + Self::Return(..) | Self::BreakLoop(..) => true, _ => false, } } @@ -658,12 +653,12 @@ impl Stmt { } match self { - Self::Var(e, _, _, _) => { + Self::Var(e, _, ..) => { if !e.walk(path, on_node) { return false; } } - Self::If(e, x, _) => { + Self::If(e, x, ..) => { if !e.walk(path, on_node) { return false; } @@ -678,7 +673,7 @@ impl Stmt { } } } - Self::Switch(e, x, _) => { + Self::Switch(e, x, ..) => { if !e.walk(path, on_node) { return false; } @@ -697,7 +692,7 @@ impl Stmt { } } } - for (_, _, _, b) in &x.ranges { + for (.., b) in &x.ranges { if !b .condition .as_ref() @@ -718,7 +713,7 @@ impl Stmt { } } } - Self::While(e, s, _) | Self::Do(s, e, _, _) => { + Self::While(e, s, ..) | Self::Do(s, e, ..) => { if !e.walk(path, on_node) { return false; } @@ -728,7 +723,7 @@ impl Stmt { } } } - Self::For(e, x, _) => { + Self::For(e, x, ..) => { if !e.walk(path, on_node) { return false; } @@ -738,7 +733,7 @@ impl Stmt { } } } - Self::Assignment(x, _) => { + Self::Assignment(x, ..) => { if !x.1.lhs.walk(path, on_node) { return false; } @@ -746,21 +741,21 @@ impl Stmt { return false; } } - Self::FnCall(x, _) => { + Self::FnCall(x, ..) => { for s in &x.args { if !s.walk(path, on_node) { return false; } } } - Self::Block(x, _) => { + Self::Block(x, ..) => { for s in x.iter() { if !s.walk(path, on_node) { return false; } } } - Self::TryCatch(x, _) => { + Self::TryCatch(x, ..) => { for s in x.try_block.iter() { if !s.walk(path, on_node) { return false; @@ -778,7 +773,7 @@ impl Stmt { } } #[cfg(not(feature = "no_module"))] - Self::Import(e, _, _) => { + Self::Import(e, ..) => { if !e.walk(path, on_node) { return false; } diff --git a/src/bin/rhai-dbg.rs b/src/bin/rhai-dbg.rs index 7e62e34c..d5b9de06 100644 --- a/src/bin/rhai-dbg.rs +++ b/src/bin/rhai-dbg.rs @@ -584,7 +584,7 @@ fn main() { while let Err(err) = engine.run_ast_with_scope(&mut Scope::new(), &main_ast) { match *err { // Loop back to restart - EvalAltResult::ErrorTerminated(_, _) => (), + EvalAltResult::ErrorTerminated(..) => (), // Break evaluation _ => { print_error(&script, *err); diff --git a/src/bin/rhai-repl.rs b/src/bin/rhai-repl.rs index c23eab2e..8328dbe8 100644 --- a/src/bin/rhai-repl.rs +++ b/src/bin/rhai-repl.rs @@ -489,7 +489,7 @@ fn main() { .iter() .rev() .enumerate() - .find(|&(_, h)| h.contains(text)) + .find(|&(.., h)| h.contains(text)) { replacement = Some(line.clone()); replacement_index = history_offset + (rl.history().len() - 1 - n); @@ -514,7 +514,7 @@ fn main() { .iter() .rev() .enumerate() - .find(|&(_, h)| h.trim_start().starts_with(prefix)) + .find(|&(.., h)| h.trim_start().starts_with(prefix)) { replacement = Some(line.clone()); replacement_index = history_offset + (rl.history().len() - 1 - n); diff --git a/src/engine.rs b/src/engine.rs index e281c77c..eaefc5dd 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -323,7 +323,7 @@ impl Engine { match result { Ok(ref mut r) => { // Concentrate all empty strings into one instance to save memory - if let Dynamic(Union::Str(s, _, _)) = r { + if let Dynamic(Union::Str(s, ..)) = r { if s.is_empty() { if !s.ptr_eq(&self.empty_string) { *s = self.const_empty_string(); diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index a9a34adf..84c4a219 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -25,9 +25,9 @@ impl From<&Expr> for ChainType { fn from(expr: &Expr) -> Self { match expr { #[cfg(not(feature = "no_index"))] - Expr::Index(_, _, _) => Self::Indexing, + Expr::Index(..) => Self::Indexing, #[cfg(not(feature = "no_object"))] - Expr::Dot(_, _, _) => Self::Dotting, + Expr::Dot(..) => Self::Dotting, expr => unreachable!("Expr::Index or Expr::Dot expected but gets {:?}", expr), } } @@ -58,7 +58,7 @@ impl ChainArgument { #[must_use] pub fn into_index_value(self) -> Option { match self { - Self::IndexValue(value, _) => Some(value), + Self::IndexValue(value, ..) => Some(value), #[cfg(not(feature = "no_object"))] _ => None, } @@ -89,9 +89,9 @@ impl ChainArgument { #[cfg(not(feature = "no_object"))] ChainArgument::Property(pos) => *pos, #[cfg(not(feature = "no_object"))] - ChainArgument::MethodCallArgs(_, pos) => *pos, + ChainArgument::MethodCallArgs(.., pos) => *pos, #[cfg(not(feature = "no_index"))] - ChainArgument::IndexValue(_, pos) => *pos, + ChainArgument::IndexValue(.., pos) => *pos, } } /// Create n [`MethodCallArgs`][ChainArgument::MethodCallArgs]. @@ -193,7 +193,7 @@ impl Engine { true, root_pos, level, ) { // Just ignore if there is no index setter - if !matches!(*err, ERR::ErrorFunctionNotFound(_, _)) { + if !matches!(*err, ERR::ErrorFunctionNotFound(..)) { return Err(err); } } @@ -225,9 +225,7 @@ impl Engine { } // Can't index - try to call an index setter #[cfg(not(feature = "no_index"))] - Err(err) if matches!(*err, ERR::ErrorIndexingType(_, _)) => { - Some(new_val) - } + Err(err) if matches!(*err, ERR::ErrorIndexingType(..)) => Some(new_val), // Any other error Err(err) => return Err(err), }; @@ -283,11 +281,11 @@ impl Engine { result } // xxx.fn_name(...) = ??? - Expr::FnCall(_, _) if new_val.is_some() => { + Expr::FnCall(..) if new_val.is_some() => { unreachable!("method call cannot be assigned to") } // xxx.module::fn_name(...) - syntax error - Expr::FnCall(_, _) => { + Expr::FnCall(..) => { unreachable!("function call in dot chain should not be namespace-qualified") } // {xxx:map}.id op= ??? @@ -333,14 +331,14 @@ impl Engine { if op_info.is_some() { let hash = crate::ast::FnCallHashes::from_native(*hash_get); let args = &mut [target.as_mut()]; - let (mut orig_val, _) = self + let (mut orig_val, ..) = self .exec_fn_call( None, global, state, lib, getter, hash, args, is_ref_mut, true, *pos, level, ) .or_else(|err| match *err { // Try an indexer if property does not exist - ERR::ErrorDotExpr(_, _) => { + ERR::ErrorDotExpr(..) => { let prop = name.into(); self.get_indexed_mut( global, state, lib, target, prop, *pos, false, true, @@ -349,7 +347,7 @@ impl Engine { .map(|v| (v.take_or_clone(), false)) .map_err( |idx_err| match *idx_err { - ERR::ErrorIndexingType(_, _) => err, + ERR::ErrorIndexingType(..) => err, _ => idx_err, }, ) @@ -381,7 +379,7 @@ impl Engine { ) .or_else(|err| match *err { // Try an indexer if property does not exist - ERR::ErrorDotExpr(_, _) => { + ERR::ErrorDotExpr(..) => { let args = &mut [target, &mut name.into(), &mut new_val]; let fn_name = crate::engine::FN_IDX_SET; let hash_set = @@ -394,7 +392,7 @@ impl Engine { ) .map_err( |idx_err| match *idx_err { - ERR::ErrorIndexingType(_, _) => err, + ERR::ErrorIndexingType(..) => err, _ => idx_err, }, ) @@ -417,7 +415,7 @@ impl Engine { .map_or_else( |err| match *err { // Try an indexer if property does not exist - ERR::ErrorDotExpr(_, _) => { + ERR::ErrorDotExpr(..) => { let prop = name.into(); self.get_indexed_mut( global, state, lib, target, prop, *pos, false, true, level, @@ -425,7 +423,7 @@ impl Engine { .map(|v| (v.take_or_clone(), false)) .map_err(|idx_err| { match *idx_err { - ERR::ErrorIndexingType(_, _) => err, + ERR::ErrorIndexingType(..) => err, _ => idx_err, } }) @@ -433,7 +431,7 @@ impl Engine { _ => Err(err), }, // Assume getters are always pure - |(v, _)| Ok((v, false)), + |(v, ..)| Ok((v, false)), ) } // {xxx:map}.sub_lhs[expr] | {xxx:map}.sub_lhs.expr @@ -475,7 +473,7 @@ impl Engine { result?.0.into() } // {xxx:map}.module::fn_name(...) - syntax error - Expr::FnCall(_, _) => unreachable!( + Expr::FnCall(..) => unreachable!( "function call in dot chain should not be namespace-qualified" ), // Others - syntax error @@ -509,14 +507,14 @@ impl Engine { let args = &mut arg_values[..1]; // Assume getters are always pure - let (mut val, _) = self + let (mut val, ..) = self .exec_fn_call( None, global, state, lib, getter, hash_get, args, is_ref_mut, true, pos, level, ) .or_else(|err| match *err { // Try an indexer if property does not exist - ERR::ErrorDotExpr(_, _) => { + ERR::ErrorDotExpr(..) => { let prop = name.into(); self.get_indexed_mut( global, state, lib, target, prop, pos, false, true, @@ -525,7 +523,7 @@ impl Engine { .map(|v| (v.take_or_clone(), false)) .map_err( |idx_err| match *idx_err { - ERR::ErrorIndexingType(_, _) => err, + ERR::ErrorIndexingType(..) => err, _ => idx_err, }, ) @@ -565,7 +563,7 @@ impl Engine { .or_else( |err| match *err { // Try an indexer if property does not exist - ERR::ErrorDotExpr(_, _) => { + ERR::ErrorDotExpr(..) => { let args = &mut [target.as_mut(), &mut name.into(), val]; let fn_name = crate::engine::FN_IDX_SET; @@ -578,7 +576,7 @@ impl Engine { args, is_ref_mut, true, pos, level, ) .or_else(|idx_err| match *idx_err { - ERR::ErrorIndexingType(_, _) => { + ERR::ErrorIndexingType(..) => { // If there is no setter, no need to feed it back because // the property is read-only Ok((Dynamic::UNIT, false)) @@ -621,7 +619,7 @@ impl Engine { .map_err(|err| err.fill_position(pos)) } // xxx.module::fn_name(...) - syntax error - Expr::FnCall(_, _) => unreachable!( + Expr::FnCall(..) => unreachable!( "function call in dot chain should not be namespace-qualified" ), // Others - syntax error @@ -665,14 +663,14 @@ impl Engine { match lhs { // id.??? or id[???] - Expr::Variable(_, var_pos, x) => { + Expr::Variable(.., var_pos, x) => { #[cfg(feature = "debugging")] self.run_debugger(scope, global, state, lib, this_ptr, lhs, level)?; #[cfg(not(feature = "unchecked"))] self.inc_operations(&mut global.num_operations, *var_pos)?; - let (mut target, _) = + let (mut target, ..) = self.search_namespace(scope, global, state, lib, this_ptr, lhs, level)?; let obj_ptr = &mut target; @@ -682,7 +680,7 @@ impl Engine { global, state, lib, &mut None, obj_ptr, root, expr, rhs, term, idx_values, chain_type, level, new_val, ) - .map(|(v, _)| v) + .map(|(v, ..)| v) .map_err(|err| err.fill_position(op_pos)) } // {expr}.??? = ??? or {expr}[???] = ??? @@ -696,7 +694,7 @@ impl Engine { global, state, lib, this_ptr, obj_ptr, root, expr, rhs, term, idx_values, chain_type, level, new_val, ) - .map(|(v, _)| if is_assignment { Dynamic::UNIT } else { v }) + .map(|(v, ..)| if is_assignment { Dynamic::UNIT } else { v }) .map_err(|err| err.fill_position(op_pos)) } } @@ -726,7 +724,7 @@ impl Engine { match expr { #[cfg(not(feature = "no_object"))] - Expr::FnCall(x, _) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => { + Expr::FnCall(x, ..) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => { let crate::ast::FnCallExpr { args, constants, .. } = x.as_ref(); @@ -748,29 +746,29 @@ impl Engine { idx_values.push(super::ChainArgument::from_fn_call_args(values, pos)); } #[cfg(not(feature = "no_object"))] - Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dotting => { + Expr::FnCall(..) if _parent_chain_type == ChainType::Dotting => { unreachable!("function call in dot chain should not be namespace-qualified") } #[cfg(not(feature = "no_object"))] - Expr::Property(_, pos) if _parent_chain_type == ChainType::Dotting => { + Expr::Property(.., pos) if _parent_chain_type == ChainType::Dotting => { idx_values.push(super::ChainArgument::Property(*pos)) } - Expr::Property(_, _) => unreachable!("unexpected Expr::Property for indexing"), + Expr::Property(..) => unreachable!("unexpected Expr::Property for indexing"), - Expr::Index(x, term, _) | Expr::Dot(x, term, _) if !terminate_chaining => { + Expr::Index(x, term, ..) | Expr::Dot(x, term, ..) if !terminate_chaining => { let crate::ast::BinaryExpr { lhs, rhs, .. } = x.as_ref(); // Evaluate in left-to-right order let lhs_arg_val = match lhs { #[cfg(not(feature = "no_object"))] - Expr::Property(_, pos) if _parent_chain_type == ChainType::Dotting => { + Expr::Property(.., pos) if _parent_chain_type == ChainType::Dotting => { super::ChainArgument::Property(*pos) } - Expr::Property(_, _) => unreachable!("unexpected Expr::Property for indexing"), + Expr::Property(..) => unreachable!("unexpected Expr::Property for indexing"), #[cfg(not(feature = "no_object"))] - Expr::FnCall(x, _) + Expr::FnCall(x, ..) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => { let crate::ast::FnCallExpr { @@ -793,7 +791,7 @@ impl Engine { super::ChainArgument::from_fn_call_args(values, pos) } #[cfg(not(feature = "no_object"))] - Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dotting => { + Expr::FnCall(..) if _parent_chain_type == ChainType::Dotting => { unreachable!("function call in dot chain should not be namespace-qualified") } #[cfg(not(feature = "no_object"))] @@ -862,7 +860,7 @@ impl Engine { match target { #[cfg(not(feature = "no_index"))] - Dynamic(Union::Array(arr, _, _)) => { + Dynamic(Union::Array(arr, ..)) => { // val_array[idx] let index = idx .as_int() @@ -876,7 +874,7 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Dynamic(Union::Blob(arr, _, _)) => { + Dynamic(Union::Blob(arr, ..)) => { // val_blob[idx] let index = idx .as_int() @@ -896,7 +894,7 @@ impl Engine { } #[cfg(not(feature = "no_object"))] - Dynamic(Union::Map(map, _, _)) => { + Dynamic(Union::Map(map, ..)) => { // val_map[idx] let index = idx.read_lock::().ok_or_else(|| { self.make_type_mismatch_err::(idx.type_name(), pos) @@ -913,7 +911,7 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Dynamic(Union::Int(value, _, _)) + Dynamic(Union::Int(value, ..)) if idx.is::() || idx.is::() => { // val_int[range] @@ -984,7 +982,7 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Dynamic(Union::Int(value, _, _)) => { + Dynamic(Union::Int(value, ..)) => { // val_int[idx] let index = idx .as_int() @@ -1006,7 +1004,7 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Dynamic(Union::Str(s, _, _)) => { + Dynamic(Union::Str(s, ..)) => { // val_string[idx] let index = idx .as_int() @@ -1052,7 +1050,7 @@ impl Engine { self.exec_fn_call( None, global, state, lib, fn_name, hash_get, args, true, true, pos, level, ) - .map(|(v, _)| v.into()) + .map(|(v, ..)| v.into()) } _ => Err(ERR::ErrorIndexingType( diff --git a/src/eval/data_check.rs b/src/eval/data_check.rs index c09197d2..29d39406 100644 --- a/src/eval/data_check.rs +++ b/src/eval/data_check.rs @@ -21,51 +21,51 @@ impl Engine { match value.0 { #[cfg(not(feature = "no_index"))] - Union::Array(ref arr, _, _) => { + Union::Array(ref arr, ..) => { arr.iter() .fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 { - Union::Array(_, _, _) => { + Union::Array(..) => { let (a, m, s) = Self::calc_data_sizes(value, false); (arrays + a + 1, maps + m, strings + s) } - Union::Blob(ref a, _, _) => (arrays + 1 + a.len(), maps, strings), + Union::Blob(ref a, ..) => (arrays + 1 + a.len(), maps, strings), #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => { + Union::Map(..) => { let (a, m, s) = Self::calc_data_sizes(value, false); (arrays + a + 1, maps + m, strings + s) } - Union::Str(ref s, _, _) => (arrays + 1, maps, strings + s.len()), + Union::Str(ref s, ..) => (arrays + 1, maps, strings + s.len()), _ => (arrays + 1, maps, strings), }) } #[cfg(not(feature = "no_index"))] - Union::Blob(ref arr, _, _) => (arr.len(), 0, 0), + Union::Blob(ref arr, ..) => (arr.len(), 0, 0), #[cfg(not(feature = "no_object"))] - Union::Map(ref map, _, _) => { + Union::Map(ref map, ..) => { map.values() .fold((0, 0, 0), |(arrays, maps, strings), value| match value.0 { #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => { + Union::Array(..) => { let (a, m, s) = Self::calc_data_sizes(value, false); (arrays + a, maps + m + 1, strings + s) } #[cfg(not(feature = "no_index"))] - Union::Blob(ref a, _, _) => (arrays + a.len(), maps, strings), - Union::Map(_, _, _) => { + Union::Blob(ref a, ..) => (arrays + a.len(), maps, strings), + Union::Map(..) => { let (a, m, s) = Self::calc_data_sizes(value, false); (arrays + a, maps + m + 1, strings + s) } - Union::Str(ref s, _, _) => (arrays, maps + 1, strings + s.len()), + Union::Str(ref s, ..) => (arrays, maps + 1, strings + s.len()), _ => (arrays, maps + 1, strings), }) } - Union::Str(ref s, _, _) => (0, 0, s.len()), + Union::Str(ref s, ..) => (0, 0, s.len()), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) if _top => { + Union::Shared(..) if _top => { Self::calc_data_sizes(&*value.read_lock::().unwrap(), true) } #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => { + Union::Shared(..) => { unreachable!("shared values discovered within data: {}", value) } _ => (0, 0, 0), diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index d585439b..70aa50c2 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -271,7 +271,7 @@ impl Debugger { } else { DebuggerStatus::CONTINUE }, - state: if let Some((ref init, _)) = engine.debugger { + state: if let Some((ref init, ..)) = engine.debugger { init() } else { Dynamic::UNIT @@ -348,8 +348,8 @@ impl Debugger { self.break_points() .iter() .enumerate() - .filter(|&(_, bp)| bp.is_enabled()) - .find(|&(_, bp)| match bp { + .filter(|&(.., bp)| bp.is_enabled()) + .find(|&(.., bp)| match bp { #[cfg(not(feature = "no_position"))] BreakPoint::AtPosition { pos, .. } if pos.is_none() => false, #[cfg(not(feature = "no_position"))] @@ -361,26 +361,26 @@ impl Debugger { node.position() == *pos && _src == source } BreakPoint::AtFunctionName { name, .. } => match node { - ASTNode::Expr(Expr::FnCall(x, _)) - | ASTNode::Stmt(Stmt::FnCall(x, _)) - | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, _))) => x.name == *name, + ASTNode::Expr(Expr::FnCall(x, ..)) + | ASTNode::Stmt(Stmt::FnCall(x, ..)) + | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => x.name == *name, _ => false, }, BreakPoint::AtFunctionCall { name, args, .. } => match node { - ASTNode::Expr(Expr::FnCall(x, _)) - | ASTNode::Stmt(Stmt::FnCall(x, _)) - | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, _))) => { + ASTNode::Expr(Expr::FnCall(x, ..)) + | ASTNode::Stmt(Stmt::FnCall(x, ..)) + | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => { x.args.len() == *args && x.name == *name } _ => false, }, #[cfg(not(feature = "no_object"))] BreakPoint::AtProperty { name, .. } => match node { - ASTNode::Expr(Expr::Property(x, _)) => x.2 == *name, + ASTNode::Expr(Expr::Property(x, ..)) => x.2 == *name, _ => false, }, }) - .map(|(i, _)| i) + .map(|(i, ..)| i) } /// Get a slice of all [`BreakPoint`]'s. #[inline(always)] @@ -525,7 +525,7 @@ impl Engine { level, }; - if let Some((_, ref on_debugger)) = self.debugger { + if let Some((.., ref on_debugger)) = self.debugger { let command = on_debugger(&mut context, event, node, source, node.position())?; match command { @@ -548,9 +548,9 @@ impl Engine { DebuggerCommand::FunctionExit => { // Bump a level if it is a function call let level = match node { - ASTNode::Expr(Expr::FnCall(_, _)) - | ASTNode::Stmt(Stmt::FnCall(_, _)) - | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(_, _))) => context.call_level() + 1, + ASTNode::Expr(Expr::FnCall(..)) + | ASTNode::Stmt(Stmt::FnCall(..)) + | ASTNode::Stmt(Stmt::Expr(Expr::FnCall(..))) => context.call_level() + 1, _ => context.call_level(), }; global.debugger.status = DebuggerStatus::FunctionExit(level); diff --git a/src/eval/expr.rs b/src/eval/expr.rs index 67bc06b8..a82504b1 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -53,7 +53,7 @@ impl Engine { level: usize, ) -> RhaiResultOf<(Target<'s>, Position)> { match expr { - Expr::Variable(Some(_), _, _) => { + Expr::Variable(Some(_), ..) => { self.search_scope_only(scope, global, state, lib, this_ptr, expr, level) } Expr::Variable(None, _var_pos, v) => match v.as_ref() { @@ -80,7 +80,7 @@ impl Engine { Ok((target.into(), *_var_pos)) } Err(err) => Err(match *err { - ERR::ErrorVariableNotFound(_, _) => ERR::ErrorVariableNotFound( + ERR::ErrorVariableNotFound(..) => ERR::ErrorVariableNotFound( format!( "{}{}{}", namespace, @@ -155,7 +155,7 @@ impl Engine { } } _ if state.always_search_scope => (0, expr.start_position()), - Expr::Variable(Some(i), pos, _) => (i.get() as usize, *pos), + Expr::Variable(Some(i), pos, ..) => (i.get() as usize, *pos), Expr::Variable(None, pos, v) => (v.0.map(NonZeroUsize::get).unwrap_or(0), *pos), _ => unreachable!("Expr::Variable expected but gets {:?}", expr), }; @@ -270,7 +270,7 @@ impl Engine { // Function calls should account for a relatively larger portion of expressions because // binary operators are also function calls. - if let Expr::FnCall(x, _) = expr { + if let Expr::FnCall(x, ..) = expr { #[cfg(feature = "debugging")] let reset_debugger = self.run_debugger_with_reset(scope, global, state, lib, this_ptr, expr, level)?; @@ -304,7 +304,7 @@ impl Engine { .ok_or_else(|| ERR::ErrorUnboundThis(*var_pos).into()) } else { self.search_namespace(scope, global, state, lib, this_ptr, expr, level) - .map(|(val, _)| val.take_or_clone()) + .map(|(val, ..)| val.take_or_clone()) }; } @@ -317,13 +317,13 @@ impl Engine { let result = match expr { // Constants - Expr::DynamicConstant(x, _) => Ok(x.as_ref().clone()), - Expr::IntegerConstant(x, _) => Ok((*x).into()), + Expr::DynamicConstant(x, ..) => Ok(x.as_ref().clone()), + Expr::IntegerConstant(x, ..) => Ok((*x).into()), #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(x, _) => Ok((*x).into()), - Expr::StringConstant(x, _) => Ok(x.clone().into()), - Expr::CharConstant(x, _) => Ok((*x).into()), - Expr::BoolConstant(x, _) => Ok((*x).into()), + Expr::FloatConstant(x, ..) => Ok((*x).into()), + Expr::StringConstant(x, ..) => Ok(x.clone().into()), + Expr::CharConstant(x, ..) => Ok((*x).into()), + Expr::BoolConstant(x, ..) => Ok((*x).into()), Expr::Unit(_) => Ok(Dynamic::UNIT), // `... ${...} ...` @@ -364,7 +364,7 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Expr::Array(x, _) => { + Expr::Array(x, ..) => { let mut arr = crate::Array::with_capacity(x.len()); let mut result = Ok(Dynamic::UNIT); @@ -402,7 +402,7 @@ impl Engine { } #[cfg(not(feature = "no_object"))] - Expr::Map(x, _) => { + Expr::Map(x, ..) => { let mut map = x.1.clone(); let mut result = Ok(Dynamic::UNIT); @@ -440,7 +440,7 @@ impl Engine { result.map(|_| map.into()) } - Expr::And(x, _) => { + Expr::And(x, ..) => { let lhs = self .eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level) .and_then(|v| { @@ -463,7 +463,7 @@ impl Engine { } } - Expr::Or(x, _) => { + Expr::Or(x, ..) => { let lhs = self .eval_expr(scope, global, state, lib, this_ptr, &x.lhs, level) .and_then(|v| { @@ -519,12 +519,12 @@ impl Engine { } #[cfg(not(feature = "no_index"))] - Expr::Index(_, _, _) => { + Expr::Index(..) => { self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None) } #[cfg(not(feature = "no_object"))] - Expr::Dot(_, _, _) => { + Expr::Dot(..) => { self.eval_dot_index_chain(scope, global, state, lib, this_ptr, expr, level, None) } diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 9c43ea42..e57a9929 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -67,13 +67,13 @@ impl Engine { } #[cfg(not(feature = "no_module"))] - if matches!(stmt, Stmt::Import(_, _, _)) { + if matches!(stmt, Stmt::Import(..)) { // Get the extra modules - see if any functions are marked global. // Without global functions, the extra modules never affect function resolution. if global .scan_imports_raw() .skip(imports_len) - .any(|(_, m)| m.contains_indexed_global_functions()) + .any(|(.., m)| m.contains_indexed_global_functions()) { if state.fn_resolution_caches_len() > orig_fn_resolution_caches_len { // When new module is imported with global functions and there is already @@ -162,10 +162,10 @@ impl Engine { #[cfg(not(feature = "unchecked"))] self.check_data_size(&args[0], root.1)?; } - Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, _) if f.starts_with(op_assign)) => + Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, ..) if f.starts_with(op_assign)) => { // Expand to `var = var op rhs` - let (value, _) = self.call_native_fn( + let (value, ..) = self.call_native_fn( global, state, lib, op, hash_op, args, true, false, op_pos, level, )?; @@ -211,7 +211,7 @@ impl Engine { // Popular branches are lifted out of the `match` statement into their own branches. // Function calls should account for a relatively larger portion of statements. - if let Stmt::FnCall(x, _) = stmt { + if let Stmt::FnCall(x, ..) = stmt { #[cfg(not(feature = "unchecked"))] self.inc_operations(&mut global.num_operations, stmt.position())?; @@ -288,19 +288,19 @@ impl Engine { // Must be either `var[index] op= val` or `var.prop op= val` match lhs { // name op= rhs (handled above) - Expr::Variable(_, _, _) => { + Expr::Variable(..) => { unreachable!("Expr::Variable case is already handled") } // idx_lhs[idx_expr] op= rhs #[cfg(not(feature = "no_index"))] - Expr::Index(_, _, _) => self + Expr::Index(..) => self .eval_dot_index_chain( scope, global, state, lib, this_ptr, lhs, level, _new_val, ) .map(|_| Dynamic::UNIT), // dot_lhs.dot_rhs op= rhs #[cfg(not(feature = "no_object"))] - Expr::Dot(_, _, _) => self + Expr::Dot(..) => self .eval_dot_index_chain( scope, global, state, lib, this_ptr, lhs, level, _new_val, ) @@ -331,13 +331,13 @@ impl Engine { .map(Dynamic::flatten), // Block scope - Stmt::Block(statements, _) if statements.is_empty() => Ok(Dynamic::UNIT), - Stmt::Block(statements, _) => { + Stmt::Block(statements, ..) if statements.is_empty() => Ok(Dynamic::UNIT), + Stmt::Block(statements, ..) => { self.eval_stmt_block(scope, global, state, lib, this_ptr, statements, true, level) } // If statement - Stmt::If(expr, x, _) => { + Stmt::If(expr, x, ..) => { let guard_val = self .eval_expr(scope, global, state, lib, this_ptr, expr, level) .and_then(|v| { @@ -370,7 +370,7 @@ impl Engine { } // Switch statement - Stmt::Switch(match_expr, x, _) => { + Stmt::Switch(match_expr, x, ..) => { let SwitchCases { cases, def_case, @@ -414,8 +414,8 @@ impl Engine { let value = value.as_int().expect("`INT`"); let mut result = Ok(None); - for (_, _, _, block) in - ranges.iter().filter(|&&(start, end, inclusive, _)| { + for (.., block) in + ranges.iter().filter(|&&(start, end, inclusive, ..)| { (!inclusive && (start..end).contains(&value)) || (inclusive && (start..=end).contains(&value)) }) @@ -483,15 +483,15 @@ impl Engine { } // Loop - Stmt::While(Expr::Unit(_), body, _) => loop { + Stmt::While(Expr::Unit(_), body, ..) => loop { if !body.is_empty() { match self .eval_stmt_block(scope, global, state, lib, this_ptr, body, true, level) { Ok(_) => (), Err(err) => match *err { - ERR::LoopBreak(false, _) => (), - ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT), + ERR::LoopBreak(false, ..) => (), + ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT), _ => break Err(err), }, } @@ -502,7 +502,7 @@ impl Engine { }, // While loop - Stmt::While(expr, body, _) => loop { + Stmt::While(expr, body, ..) => loop { let condition = self .eval_expr(scope, global, state, lib, this_ptr, expr, level) .and_then(|v| { @@ -520,8 +520,8 @@ impl Engine { { Ok(_) => (), Err(err) => match *err { - ERR::LoopBreak(false, _) => (), - ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT), + ERR::LoopBreak(false, ..) => (), + ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT), _ => break Err(err), }, } @@ -531,7 +531,7 @@ impl Engine { }, // Do loop - Stmt::Do(body, expr, options, _) => loop { + Stmt::Do(body, expr, options, ..) => loop { let is_while = !options.contains(AST_OPTION_NEGATED); if !body.is_empty() { @@ -540,8 +540,8 @@ impl Engine { { Ok(_) => (), Err(err) => match *err { - ERR::LoopBreak(false, _) => continue, - ERR::LoopBreak(true, _) => break Ok(Dynamic::UNIT), + ERR::LoopBreak(false, ..) => continue, + ERR::LoopBreak(true, ..) => break Ok(Dynamic::UNIT), _ => break Err(err), }, } @@ -563,7 +563,7 @@ impl Engine { }, // For loop - Stmt::For(expr, x, _) => { + Stmt::For(expr, x, ..) => { let (Ident { name: var_name, .. }, counter, statements) = x.as_ref(); let iter_result = self @@ -672,8 +672,8 @@ impl Engine { match result { Ok(_) => (), Err(err) => match *err { - ERR::LoopBreak(false, _) => (), - ERR::LoopBreak(true, _) => break, + ERR::LoopBreak(false, ..) => (), + ERR::LoopBreak(true, ..) => break, _ => { loop_result = Err(err); break; @@ -699,7 +699,7 @@ impl Engine { } // Try/Catch statement - Stmt::TryCatch(x, _) => { + Stmt::TryCatch(x, ..) => { let TryCatchBlock { try_block, catch_var, @@ -716,7 +716,7 @@ impl Engine { Err(err) if !err.is_catchable() => Err(err), Err(mut err) => { let err_value = match *err { - ERR::ErrorRuntime(ref x, _) => x.clone(), + ERR::ErrorRuntime(ref x, ..) => x.clone(), #[cfg(feature = "no_object")] _ => { @@ -773,7 +773,7 @@ impl Engine { Ok(_) => Ok(Dynamic::UNIT), Err(result_err) => match *result_err { // Re-throw exception - ERR::ErrorRuntime(Dynamic(Union::Unit(_, _, _)), pos) => { + ERR::ErrorRuntime(Dynamic(Union::Unit(..)), pos) => { err.set_position(pos); Err(err) } @@ -795,15 +795,15 @@ impl Engine { } // Return value - Stmt::Return(_, Some(expr), pos) => self + Stmt::Return(.., Some(expr), pos) => self .eval_expr(scope, global, state, lib, this_ptr, expr, level) .and_then(|v| Err(ERR::Return(v.flatten(), *pos).into())), // Empty return - Stmt::Return(_, None, pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()), + Stmt::Return(.., None, pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()), // Let/const statement - shadowing disallowed - Stmt::Var(_, x, _, pos) if !self.allow_shadowing() && scope.contains(&x.name) => { + Stmt::Var(.., x, _, pos) if !self.allow_shadowing() && scope.contains(&x.name) => { Err(ERR::ErrorVariableExists(x.name.to_string(), *pos).into()) } // Let/const statement @@ -924,7 +924,7 @@ impl Engine { let module_result = resolver .as_ref() .and_then(|r| match r.resolve_raw(self, global, &path, path_pos) { - Err(err) if matches!(*err, ERR::ErrorModuleNotFound(_, _)) => None, + Err(err) if matches!(*err, ERR::ErrorModuleNotFound(..)) => None, result => Some(result), }) .or_else(|| { @@ -961,10 +961,10 @@ impl Engine { // Export statement #[cfg(not(feature = "no_module"))] - Stmt::Export(x, _) => { + Stmt::Export(x, ..) => { let (Ident { name, pos, .. }, Ident { name: alias, .. }) = x.as_ref(); // Mark scope variables as public - if let Some((index, _)) = scope.get_index(name) { + if let Some((index, ..)) = scope.get_index(name) { scope.add_entry_alias( index, if alias.is_empty() { name } else { alias }.clone(), @@ -978,7 +978,7 @@ impl Engine { // Share statement #[cfg(not(feature = "no_closure"))] Stmt::Share(name) => { - if let Some((index, _)) = scope.get_index(name) { + if let Some((index, ..)) = scope.get_index(name) { let val = scope.get_mut_by_index(index); if !val.is_shared() { diff --git a/src/func/call.rs b/src/func/call.rs index fdd6c932..56311890 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -109,11 +109,11 @@ pub fn ensure_no_data_race( args: &FnCallArgs, is_method_call: bool, ) -> RhaiResultOf<()> { - if let Some((n, _)) = args + if let Some((n, ..)) = args .iter() .enumerate() .skip(if is_method_call { 1 } else { 0 }) - .find(|(_, a)| a.is_locked()) + .find(|(.., a)| a.is_locked()) { return Err(ERR::ErrorDataRace( format!("argument #{} of function '{}'", n + 1, fn_name), @@ -392,7 +392,7 @@ impl Engine { let source = match (source.as_str(), parent_source.as_str()) { ("", "") => None, - ("", s) | (s, _) => Some(s), + ("", s) | (s, ..) => Some(s), }; #[cfg(feature = "debugging")] @@ -430,7 +430,7 @@ impl Engine { { let trigger = match global.debugger.status { crate::eval::DebuggerStatus::FunctionExit(n) => n >= level, - crate::eval::DebuggerStatus::Next(_, true) => true, + crate::eval::DebuggerStatus::Next(.., true) => true, _ => false, }; if trigger { @@ -774,8 +774,8 @@ impl Engine { scope, global, state, lib, &mut None, statements, false, level, ) .or_else(|err| match *err { - ERR::Return(out, _) => Ok(out), - ERR::LoopBreak(_, _) => { + ERR::Return(out, ..) => Ok(out), + ERR::LoopBreak(..) => { unreachable!("no outer loop scope to break out of") } _ => Err(err), @@ -958,7 +958,7 @@ impl Engine { level: usize, ) -> RhaiResultOf<(Dynamic, Position)> { Ok(( - if let Expr::Stack(slot, _) = arg_expr { + if let Expr::Stack(slot, ..) = arg_expr { #[cfg(feature = "debugging")] self.run_debugger(scope, global, state, lib, this_ptr, arg_expr, level)?; constants[*slot].clone() @@ -1081,7 +1081,7 @@ impl Engine { a_expr .iter() .try_fold(fn_curry, |mut curried, expr| -> RhaiResultOf<_> { - let (value, _) = self.get_arg_value( + let (value, ..) = self.get_arg_value( scope, global, state, lib, this_ptr, expr, constants, level, )?; curried.push(value); @@ -1095,7 +1095,7 @@ impl Engine { #[cfg(not(feature = "no_closure"))] crate::engine::KEYWORD_IS_SHARED if total_args == 1 => { let arg = first_arg.unwrap(); - let (arg_value, _) = + let (arg_value, ..) = self.get_arg_value(scope, global, state, lib, this_ptr, arg, constants, level)?; return Ok(arg_value.is_shared().into()); } @@ -1195,7 +1195,7 @@ impl Engine { .chain(a_expr.iter()) .try_for_each(|expr| { self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level) - .map(|(value, _)| arg_values.push(value.flatten())) + .map(|(value, ..)| arg_values.push(value.flatten())) })?; args.extend(curry.iter_mut()); args.extend(arg_values.iter_mut()); @@ -1208,7 +1208,7 @@ impl Engine { scope, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos, level, ) - .map(|(v, _)| v); + .map(|(v, ..)| v); } // Call with blank scope @@ -1227,7 +1227,7 @@ impl Engine { // func(x, ...) -> x.func(...) a_expr.iter().try_for_each(|expr| { self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level) - .map(|(value, _)| arg_values.push(value.flatten())) + .map(|(value, ..)| arg_values.push(value.flatten())) })?; let (mut target, _pos) = @@ -1264,7 +1264,7 @@ impl Engine { self.get_arg_value( scope, global, state, lib, this_ptr, expr, constants, level, ) - .map(|(value, _)| arg_values.push(value.flatten())) + .map(|(value, ..)| arg_values.push(value.flatten())) })?; args.extend(curry.iter_mut()); args.extend(arg_values.iter_mut()); @@ -1274,7 +1274,7 @@ impl Engine { self.exec_fn_call( None, global, state, lib, name, hashes, &mut args, is_ref_mut, false, pos, level, ) - .map(|(v, _)| v) + .map(|(v, ..)| v) } /// Call a namespace-qualified function in normal function-call style. @@ -1313,7 +1313,7 @@ impl Engine { args_expr.iter().skip(1).try_for_each(|expr| { self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level) - .map(|(value, _)| arg_values.push(value.flatten())) + .map(|(value, ..)| arg_values.push(value.flatten())) })?; // Get target reference to first argument @@ -1344,7 +1344,7 @@ impl Engine { // func(..., ...) or func(mod::x, ...) args_expr.iter().try_for_each(|expr| { self.get_arg_value(scope, global, state, lib, this_ptr, expr, constants, level) - .map(|(value, _)| arg_values.push(value.flatten())) + .map(|(value, ..)| arg_values.push(value.flatten())) })?; args.extend(arg_values.iter_mut()); } diff --git a/src/func/native.rs b/src/func/native.rs index 380098fd..375f6f81 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -333,7 +333,7 @@ impl<'a> NativeCallContext<'a> { Position::NONE, self.level + 1, ) - .map(|(r, _)| r) + .map(|(r, ..)| r) } } diff --git a/src/func/script.rs b/src/func/script.rs index 7b4236a8..97721df5 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -103,7 +103,7 @@ impl Engine { scope .iter() .skip(orig_scope_len) - .map(|(_, _, v)| v.clone()) + .map(|(.., v)| v.clone()) .collect(), global.source.clone(), pos, @@ -161,9 +161,9 @@ impl Engine { ) .or_else(|err| match *err { // Convert return statement to return value - ERR::Return(x, _) => Ok(x), + ERR::Return(x, ..) => Ok(x), // Error in sub function call - ERR::ErrorInFunctionCall(name, src, err, _) => { + ERR::ErrorInFunctionCall(name, src, err, ..) => { let fn_name = if src.is_empty() { format!("{} < {}", name, fn_def.name) } else { @@ -185,7 +185,7 @@ impl Engine { { let trigger = match global.debugger.status { crate::eval::DebuggerStatus::FunctionExit(n) => n >= level, - crate::eval::DebuggerStatus::Next(_, true) => true, + crate::eval::DebuggerStatus::Next(.., true) => true, _ => false, }; if trigger { diff --git a/src/module/mod.rs b/src/module/mod.rs index d9b16a17..4b241288 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1402,7 +1402,7 @@ impl Module { /// Sub-modules are flattened onto the root [`Module`], with higher level overriding lower level. #[inline] pub fn combine_flatten(&mut self, other: Self) -> &mut Self { - for (_, m) in other.modules.into_iter() { + for (.., m) in other.modules.into_iter() { self.combine_flatten(shared_take_or_clone(m)); } self.variables.extend(other.variables.into_iter()); @@ -1471,7 +1471,7 @@ impl Module { other .functions .iter() - .filter(|&(_, f)| { + .filter(|&(.., f)| { _filter( f.metadata.namespace, f.metadata.access, @@ -1502,7 +1502,7 @@ impl Module { ) -> &mut Self { self.functions = std::mem::take(&mut self.functions) .into_iter() - .filter(|(_, f)| { + .filter(|(.., f)| { if f.func.is_script() { filter( f.metadata.namespace, @@ -1717,7 +1717,7 @@ impl Module { result?; // Variables with an alias left in the scope become module variables - for (_, value, mut aliases) in scope { + for (.., value, mut aliases) in scope { match aliases.len() { 0 => (), 1 => { diff --git a/src/module/resolvers/collection.rs b/src/module/resolvers/collection.rs index 8495fb8d..57c2bbb1 100644 --- a/src/module/resolvers/collection.rs +++ b/src/module/resolvers/collection.rs @@ -128,7 +128,7 @@ impl ModuleResolver for ModuleResolversCollection { match resolver.resolve(engine, source_path, path, pos) { Ok(module) => return Ok(module), Err(err) => match *err { - ERR::ErrorModuleNotFound(_, _) => continue, + ERR::ErrorModuleNotFound(..) => continue, ERR::ErrorInModule(_, err, _) => return Err(err), _ => panic!("ModuleResolver::resolve returns error that is not ErrorModuleNotFound or ErrorInModule"), }, diff --git a/src/module/resolvers/file.rs b/src/module/resolvers/file.rs index 1f06fb94..8ed6c7e7 100644 --- a/src/module/resolvers/file.rs +++ b/src/module/resolvers/file.rs @@ -230,7 +230,7 @@ impl FileModuleResolver { locked_write(&self.cache) .remove_entry(&file_path) - .map(|(_, v)| v) + .map(|(.., v)| v) } /// Construct a full file path. #[must_use] @@ -288,7 +288,7 @@ impl FileModuleResolver { let mut ast = engine .compile_file(file_path.clone()) .map_err(|err| match *err { - ERR::ErrorSystem(_, err) if err.is::() => { + ERR::ErrorSystem(.., err) if err.is::() => { Box::new(ERR::ErrorModuleNotFound(path.to_string(), pos)) } _ => Box::new(ERR::ErrorInModule(path.to_string(), err, pos)), @@ -356,7 +356,7 @@ impl ModuleResolver for FileModuleResolver { ast }) .map_err(|err| match *err { - ERR::ErrorSystem(_, err) if err.is::() => { + ERR::ErrorSystem(.., err) if err.is::() => { ERR::ErrorModuleNotFound(path.to_string(), pos).into() } _ => ERR::ErrorInModule(path.to_string(), err, pos).into(), diff --git a/src/optimizer.rs b/src/optimizer.rs index df9bc26d..f53c51ac 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -150,7 +150,7 @@ impl<'a> OptimizerState<'a> { 0, ) .ok() - .map(|(v, _)| v) + .map(|(v, ..)| v) } } @@ -205,13 +205,13 @@ fn optimize_stmt_block( // Flatten blocks loop { if let Some(n) = statements.iter().enumerate().find_map(|(i, s)| match s { - Stmt::Block(block, _) if !block.iter().any(Stmt::is_block_dependent) => Some(i), + Stmt::Block(block, ..) if !block.iter().any(Stmt::is_block_dependent) => Some(i), _ => None, }) { let (first, second) = statements.split_at_mut(n); let stmt = mem::take(&mut second[0]); let mut stmts = match stmt { - Stmt::Block(block, _) => block, + Stmt::Block(block, ..) => block, stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), }; statements = first @@ -252,7 +252,7 @@ fn optimize_stmt_block( // Optimize each statement in the block for stmt in statements.iter_mut() { match stmt { - Stmt::Var(value_expr, x, options, _) => { + Stmt::Var(value_expr, x, options, ..) => { if options.contains(AST_OPTION_CONSTANT) { // Add constant literals into the state optimize_expr(value_expr, state, false); @@ -284,10 +284,10 @@ fn optimize_stmt_block( .find_map(|(i, stmt)| match stmt { stmt if !is_pure(stmt) => Some(i), - Stmt::Var(e, _, _, _) | Stmt::Expr(e) if !e.is_constant() => Some(i), + Stmt::Var(e, _, ..) | Stmt::Expr(e) if !e.is_constant() => Some(i), #[cfg(not(feature = "no_module"))] - Stmt::Import(e, _, _) if !e.is_constant() => Some(i), + Stmt::Import(e, ..) if !e.is_constant() => Some(i), _ => None, }) @@ -320,7 +320,7 @@ fn optimize_stmt_block( loop { match statements[..] { // { return; } -> {} - [Stmt::Return(options, None, _)] + [Stmt::Return(options, None, ..)] if reduce_return && !options.contains(AST_OPTION_BREAK) => { state.set_dirty(); @@ -331,7 +331,7 @@ fn optimize_stmt_block( statements.clear(); } // { ...; return; } -> { ... } - [.., ref last_stmt, Stmt::Return(options, None, _)] + [.., ref last_stmt, Stmt::Return(options, None, ..)] if reduce_return && !options.contains(AST_OPTION_BREAK) && !last_stmt.returns_value() => @@ -377,14 +377,14 @@ fn optimize_stmt_block( statements.clear(); } // { ...; return; } -> { ... } - [.., Stmt::Return(options, None, _)] + [.., Stmt::Return(options, None, ..)] if reduce_return && !options.contains(AST_OPTION_BREAK) => { state.set_dirty(); statements.pop().unwrap(); } // { ...; return pure_val; } -> { ... } - [.., Stmt::Return(options, Some(ref expr), _)] + [.., Stmt::Return(options, Some(ref expr), ..)] if reduce_return && !options.contains(AST_OPTION_BREAK) && expr.is_pure() => @@ -424,17 +424,17 @@ fn optimize_stmt_block( fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: bool) { match stmt { // var = var op expr => var op= expr - Stmt::Assignment(x, _) + Stmt::Assignment(x, ..) if x.0.is_none() && x.1.lhs.is_variable_access(true) - && matches!(&x.1.rhs, Expr::FnCall(x2, _) + && matches!(&x.1.rhs, Expr::FnCall(x2, ..) if Token::lookup_from_syntax(&x2.name).map(|t| t.has_op_assignment()).unwrap_or(false) && x2.args.len() == 2 && x2.args[0].get_variable_name(true) == x.1.lhs.get_variable_name(true) ) => { match x.1.rhs { - Expr::FnCall(ref mut x2, _) => { + Expr::FnCall(ref mut x2, ..) => { state.set_dirty(); x.0 = Some(OpAssignment::new_from_base(&x2.name)); @@ -452,7 +452,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } // expr op= expr - Stmt::Assignment(x, _) => { + Stmt::Assignment(x, ..) => { if !x.1.lhs.is_variable_access(false) { optimize_expr(&mut x.1.lhs, state, false); } @@ -460,7 +460,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } // if expr {} - Stmt::If(condition, x, _) if x.0.is_empty() && x.1.is_empty() => { + Stmt::If(condition, x, ..) if x.0.is_empty() && x.1.is_empty() => { state.set_dirty(); let pos = condition.start_position(); @@ -479,12 +479,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b }; } // if false { if_block } -> Noop - Stmt::If(Expr::BoolConstant(false, pos), x, _) if x.1.is_empty() => { + Stmt::If(Expr::BoolConstant(false, pos), x, ..) if x.1.is_empty() => { state.set_dirty(); *stmt = Stmt::Noop(*pos); } // if false { if_block } else { else_block } -> else_block - Stmt::If(Expr::BoolConstant(false, _), x, _) => { + Stmt::If(Expr::BoolConstant(false, ..), x, ..) => { state.set_dirty(); *stmt = match optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false) @@ -494,7 +494,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } } // if true { if_block } else { else_block } -> if_block - Stmt::If(Expr::BoolConstant(true, _), x, _) => { + Stmt::If(Expr::BoolConstant(true, ..), x, ..) => { state.set_dirty(); *stmt = match optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false) @@ -504,7 +504,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } } // if expr { if_block } else { else_block } - Stmt::If(condition, x, _) => { + Stmt::If(condition, x, ..) => { optimize_expr(condition, state, false); *x.0 = optimize_stmt_block(mem::take(&mut *x.0), state, preserve_result, true, false); *x.1 = optimize_stmt_block(mem::take(&mut *x.1), state, preserve_result, true, false); @@ -564,11 +564,11 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b let value = value.as_int().expect("`INT`"); // Only one range or all ranges without conditions - if ranges.len() == 1 || ranges.iter().all(|(_, _, _, c)| !c.has_condition()) { - for (_, _, _, block) in + if ranges.len() == 1 || ranges.iter().all(|(.., c)| !c.has_condition()) { + for (.., block) in ranges .iter_mut() - .filter(|&&mut (start, end, inclusive, _)| { + .filter(|&&mut (start, end, inclusive, ..)| { (!inclusive && (start..end).contains(&value)) || (inclusive && (start..=end).contains(&value)) }) @@ -619,7 +619,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b let old_ranges_len = ranges.len(); - ranges.retain(|&mut (start, end, inclusive, _)| { + ranges.retain(|&mut (start, end, inclusive, ..)| { (!inclusive && (start..end).contains(&value)) || (inclusive && (start..=end).contains(&value)) }); @@ -628,7 +628,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b state.set_dirty(); } - for (_, _, _, block) in ranges.iter_mut() { + for (.., block) in ranges.iter_mut() { let statements = mem::take(&mut *block.statements); *block.statements = optimize_stmt_block(statements, state, preserve_result, true, false); @@ -636,7 +636,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Some(mut condition) = mem::take(&mut block.condition) { optimize_expr(&mut condition, state, false); match condition { - Expr::Unit(_) | Expr::BoolConstant(true, _) => state.set_dirty(), + Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(), _ => block.condition = Some(condition), } } @@ -655,7 +655,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b ); } // switch - Stmt::Switch(match_expr, x, _) => { + Stmt::Switch(match_expr, x, ..) => { optimize_expr(match_expr, state, false); for block in x.cases.values_mut() { let statements = mem::take(&mut *block.statements); @@ -665,15 +665,15 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Some(mut condition) = mem::take(&mut block.condition) { optimize_expr(&mut condition, state, false); match condition { - Expr::Unit(_) | Expr::BoolConstant(true, _) => state.set_dirty(), + Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(), _ => block.condition = Some(condition), } } } // Remove false cases - while let Some((&key, _)) = x.cases.iter().find(|(_, block)| match block.condition { - Some(Expr::BoolConstant(false, _)) => true, + while let Some((&key, ..)) = x.cases.iter().find(|(.., block)| match block.condition { + Some(Expr::BoolConstant(false, ..)) => true, _ => false, }) { state.set_dirty(); @@ -685,12 +685,12 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } // while false { block } -> Noop - Stmt::While(Expr::BoolConstant(false, pos), _, _) => { + Stmt::While(Expr::BoolConstant(false, pos), ..) => { state.set_dirty(); *stmt = Stmt::Noop(*pos) } // while expr { block } - Stmt::While(condition, body, _) => { + Stmt::While(condition, body, ..) => { optimize_expr(condition, state, false); if let Expr::BoolConstant(true, pos) = condition { *condition = Expr::Unit(*pos); @@ -719,7 +719,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } } // do { block } while false | do { block } until true -> { block } - Stmt::Do(body, Expr::BoolConstant(x, _), options, _) + Stmt::Do(body, Expr::BoolConstant(x, ..), options, ..) if *x == options.contains(AST_OPTION_NEGATED) => { state.set_dirty(); @@ -730,22 +730,22 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b ); } // do { block } while|until expr - Stmt::Do(body, condition, _, _) => { + Stmt::Do(body, condition, ..) => { optimize_expr(condition, state, false); ***body = optimize_stmt_block(mem::take(&mut **body), state, false, true, false); } // for id in expr { block } - Stmt::For(iterable, x, _) => { + Stmt::For(iterable, x, ..) => { optimize_expr(iterable, state, false); *x.2 = optimize_stmt_block(mem::take(&mut *x.2), state, false, true, false); } // let id = expr; - Stmt::Var(expr, _, options, _) if !options.contains(AST_OPTION_CONSTANT) => { + Stmt::Var(expr, _, options, ..) if !options.contains(AST_OPTION_CONSTANT) => { optimize_expr(expr, state, false) } // import expr as var; #[cfg(not(feature = "no_module"))] - Stmt::Import(expr, _, _) => optimize_expr(expr, state, false), + Stmt::Import(expr, ..) => optimize_expr(expr, state, false), // { block } Stmt::Block(statements, pos) => { let statements = mem::take(statements).into_vec().into(); @@ -765,7 +765,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b } } // try { pure try_block } catch ( var ) { catch_block } -> try_block - Stmt::TryCatch(x, _) if x.try_block.iter().all(Stmt::is_pure) => { + Stmt::TryCatch(x, ..) if x.try_block.iter().all(Stmt::is_pure) => { // If try block is pure, there will never be any exceptions state.set_dirty(); *stmt = Stmt::Block( @@ -775,14 +775,14 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b ); } // try { try_block } catch ( var ) { catch_block } - Stmt::TryCatch(x, _) => { + Stmt::TryCatch(x, ..) => { *x.try_block = optimize_stmt_block(mem::take(&mut *x.try_block), state, false, true, false); *x.catch_block = optimize_stmt_block(mem::take(&mut *x.catch_block), state, false, true, false); } // func(...) - Stmt::Expr(expr @ Expr::FnCall(_, _)) => { + Stmt::Expr(expr @ Expr::FnCall(..)) => { optimize_expr(expr, state, false); match expr { Expr::FnCall(x, pos) => { @@ -838,31 +838,31 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { } // lhs.rhs #[cfg(not(feature = "no_object"))] - Expr::Dot(x,_, _) if !_chaining => match (&mut x.lhs, &mut x.rhs) { + Expr::Dot(x,_, ..) if !_chaining => match (&mut x.lhs, &mut x.rhs) { // map.string - (Expr::Map(m, pos), Expr::Property(p, _)) if m.0.iter().all(|(_, x)| x.is_pure()) => { + (Expr::Map(m, pos), Expr::Property(p, ..)) if m.0.iter().all(|(.., x)| x.is_pure()) => { let prop = p.2.as_str(); // Map literal where everything is pure - promote the indexed item. // All other items can be thrown away. state.set_dirty(); - *expr = mem::take(&mut m.0).into_iter().find(|(x, _)| x.name == prop) - .map(|(_, mut expr)| { expr.set_position(*pos); expr }) + *expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.name == prop) + .map(|(.., mut expr)| { expr.set_position(*pos); expr }) .unwrap_or_else(|| Expr::Unit(*pos)); } // var.rhs - (Expr::Variable(_, _, _), rhs) => optimize_expr(rhs, state, true), + (Expr::Variable(..), rhs) => optimize_expr(rhs, state, true), // lhs.rhs (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); } } // ....lhs.rhs #[cfg(not(feature = "no_object"))] - Expr::Dot(x,_, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); } + Expr::Dot(x,_, ..) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); } // lhs[rhs] #[cfg(not(feature = "no_index"))] - Expr::Index(x, _, _) if !_chaining => match (&mut x.lhs, &mut x.rhs) { + Expr::Index(x, ..) if !_chaining => match (&mut x.lhs, &mut x.rhs) { // array[int] - (Expr::Array(a, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < a.len() && a.iter().all(Expr::is_pure) => { + (Expr::Array(a, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < a.len() && a.iter().all(Expr::is_pure) => { // Array literal where everything is pure - promote the indexed item. // All other items can be thrown away. state.set_dirty(); @@ -871,7 +871,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { *expr = result; } // array[-int] - (Expr::Array(a, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|n| n as usize <= a.len()).unwrap_or(false) && a.iter().all(Expr::is_pure) => { + (Expr::Array(a, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|n| n as usize <= a.len()).unwrap_or(false) && a.iter().all(Expr::is_pure) => { // Array literal where everything is pure - promote the indexed item. // All other items can be thrown away. state.set_dirty(); @@ -881,58 +881,58 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { *expr = result; } // map[string] - (Expr::Map(m, pos), Expr::StringConstant(s, _)) if m.0.iter().all(|(_, x)| x.is_pure()) => { + (Expr::Map(m, pos), Expr::StringConstant(s, ..)) if m.0.iter().all(|(.., x)| x.is_pure()) => { // Map literal where everything is pure - promote the indexed item. // All other items can be thrown away. state.set_dirty(); - *expr = mem::take(&mut m.0).into_iter().find(|(x, _)| x.name.as_str() == s.as_str()) - .map(|(_, mut expr)| { expr.set_position(*pos); expr }) + *expr = mem::take(&mut m.0).into_iter().find(|(x, ..)| x.name.as_str() == s.as_str()) + .map(|(.., mut expr)| { expr.set_position(*pos); expr }) .unwrap_or_else(|| Expr::Unit(*pos)); } // int[int] - (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < (std::mem::size_of_val(n) * 8) => { + (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < (std::mem::size_of_val(n) * 8) => { // Bit-field literal indexing - get the bit state.set_dirty(); *expr = Expr::BoolConstant((*n & (1 << (*i as usize))) != 0, *pos); } // int[-int] - (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|i| i as usize <= (std::mem::size_of_val(n) * 8)).unwrap_or(false) => { + (Expr::IntegerConstant(n, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|i| i as usize <= (std::mem::size_of_val(n) * 8)).unwrap_or(false) => { // Bit-field literal indexing - get the bit state.set_dirty(); *expr = Expr::BoolConstant((*n & (1 << (std::mem::size_of_val(n) * 8 - i.abs() as usize))) != 0, *pos); } // string[int] - (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i >= 0 && (*i as usize) < s.chars().count() => { + (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, ..)) if *i >= 0 && (*i as usize) < s.chars().count() => { // String literal indexing - get the character state.set_dirty(); *expr = Expr::CharConstant(s.chars().nth(*i as usize).unwrap(), *pos); } // string[-int] - (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, _)) if *i < 0 && i.checked_abs().map(|n| n as usize <= s.chars().count()).unwrap_or(false) => { + (Expr::StringConstant(s, pos), Expr::IntegerConstant(i, ..)) if *i < 0 && i.checked_abs().map(|n| n as usize <= s.chars().count()).unwrap_or(false) => { // String literal indexing - get the character state.set_dirty(); *expr = Expr::CharConstant(s.chars().rev().nth(i.abs() as usize - 1).unwrap(), *pos); } // var[rhs] - (Expr::Variable(_, _, _), rhs) => optimize_expr(rhs, state, true), + (Expr::Variable(..), rhs) => optimize_expr(rhs, state, true), // lhs[rhs] (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, true); } }, // ...[lhs][rhs] #[cfg(not(feature = "no_index"))] - Expr::Index(x, _, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); } + Expr::Index(x, ..) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); } // `` Expr::InterpolatedString(x, pos) if x.is_empty() => { state.set_dirty(); *expr = Expr::StringConstant(state.engine.const_empty_string(), *pos); } // `...` - Expr::InterpolatedString(x, _) if x.len() == 1 && matches!(x[0], Expr::StringConstant(_, _)) => { + Expr::InterpolatedString(x, ..) if x.len() == 1 && matches!(x[0], Expr::StringConstant(..)) => { state.set_dirty(); *expr = mem::take(&mut x[0]); } // `... ${ ... } ...` - Expr::InterpolatedString(x, _) => { + Expr::InterpolatedString(x, ..) => { x.iter_mut().for_each(|expr| optimize_expr(expr, state, false)); let mut n = 0; @@ -940,11 +940,11 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { // Merge consecutive strings while n < x.len() - 1 { match (mem::take(&mut x[n]), mem::take(&mut x[n+1])) { - (Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, _)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); } + (Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, ..)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); } (expr1, Expr::Unit(_)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } (Expr::Unit(_), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); } - (expr1, Expr::StringConstant(s, _)) if s.is_empty() => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } - (Expr::StringConstant(s, _), expr2) if s.is_empty()=> { x[n+1] = expr2; x.remove(n); state.set_dirty(); } + (expr1, Expr::StringConstant(s, ..)) if s.is_empty() => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } + (Expr::StringConstant(s, ..), expr2) if s.is_empty()=> { x[n+1] = expr2; x.remove(n); state.set_dirty(); } (expr1, expr2) => { x[n] = expr1; x[n+1] = expr2; n += 1; } } } @@ -953,47 +953,47 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { } // [ constant .. ] #[cfg(not(feature = "no_index"))] - Expr::Array(_, _) if expr.is_constant() => { + Expr::Array(..) if expr.is_constant() => { state.set_dirty(); *expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position()); } // [ items .. ] #[cfg(not(feature = "no_index"))] - Expr::Array(x, _) => x.iter_mut().for_each(|expr| optimize_expr(expr, state, false)), + Expr::Array(x, ..) => x.iter_mut().for_each(|expr| optimize_expr(expr, state, false)), // #{ key:constant, .. } #[cfg(not(feature = "no_object"))] - Expr::Map(_, _) if expr.is_constant() => { + Expr::Map(..) if expr.is_constant() => { state.set_dirty(); *expr = Expr::DynamicConstant(expr.get_literal_value().unwrap().into(), expr.position()); } // #{ key:value, .. } #[cfg(not(feature = "no_object"))] - Expr::Map(x, _) => x.0.iter_mut().for_each(|(_, expr)| optimize_expr(expr, state, false)), + Expr::Map(x, ..) => x.0.iter_mut().for_each(|(.., expr)| optimize_expr(expr, state, false)), // lhs && rhs - Expr::And(x, _) => match (&mut x.lhs, &mut x.rhs) { + Expr::And(x, ..) => match (&mut x.lhs, &mut x.rhs) { // true && rhs -> rhs - (Expr::BoolConstant(true, _), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } + (Expr::BoolConstant(true, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } // false && rhs -> false - (Expr::BoolConstant(false, pos), _) => { state.set_dirty(); *expr = Expr::BoolConstant(false, *pos); } + (Expr::BoolConstant(false, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(false, *pos); } // lhs && true -> lhs - (lhs, Expr::BoolConstant(true, _)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } + (lhs, Expr::BoolConstant(true, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } // lhs && rhs (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); } }, // lhs || rhs - Expr::Or(ref mut x, _) => match (&mut x.lhs, &mut x.rhs) { + Expr::Or(ref mut x, ..) => match (&mut x.lhs, &mut x.rhs) { // false || rhs -> rhs - (Expr::BoolConstant(false, _), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } + (Expr::BoolConstant(false, ..), rhs) => { state.set_dirty(); optimize_expr(rhs, state, false); *expr = mem::take(rhs); } // true || rhs -> true - (Expr::BoolConstant(true, pos), _) => { state.set_dirty(); *expr = Expr::BoolConstant(true, *pos); } + (Expr::BoolConstant(true, pos), ..) => { state.set_dirty(); *expr = Expr::BoolConstant(true, *pos); } // lhs || false - (lhs, Expr::BoolConstant(false, _)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } + (lhs, Expr::BoolConstant(false, ..)) => { state.set_dirty(); optimize_expr(lhs, state, false); *expr = mem::take(lhs); } // lhs || rhs (lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); } }, // eval! - Expr::FnCall(x, _) if x.name == KEYWORD_EVAL => { + Expr::FnCall(x, ..) if x.name == KEYWORD_EVAL => { state.propagate_constants = false; } // Fn @@ -1005,8 +1005,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { && x.args[0].is_constant() => { let fn_name = match x.args[0] { - Expr::Stack(slot, _) => x.constants[slot].clone(), - Expr::StringConstant(ref s, _) => s.clone().into(), + Expr::Stack(slot, ..) => x.constants[slot].clone(), + Expr::StringConstant(ref s, ..) => s.clone().into(), _ => Dynamic::UNIT }; @@ -1019,7 +1019,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { } // Do not call some special keywords - Expr::FnCall(x, _) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => { + Expr::FnCall(x, ..) if DONT_EVAL_KEYWORDS.contains(&x.name.as_ref()) => { x.args.iter_mut().for_each(|a| optimize_expr(a, state, false)); } @@ -1031,7 +1031,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { //&& !is_valid_identifier(x.name.chars()) // cannot be scripted => { let arg_values = &mut x.args.iter().map(|e| match e { - Expr::Stack(slot, _) => x.constants[*slot].clone(), + Expr::Stack(slot, ..) => x.constants[*slot].clone(), _ => e.get_literal_value().unwrap() }).collect::>(); @@ -1097,7 +1097,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { if !has_script_fn { let arg_values = &mut x.args.iter().map(|e| match e { - Expr::Stack(slot, _) => x.constants[*slot].clone(), + Expr::Stack(slot, ..) => x.constants[*slot].clone(), _ => e.get_literal_value().unwrap() }).collect::>(); @@ -1119,7 +1119,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { } // id(args ..) -> optimize function call arguments - Expr::FnCall(x, _) => for arg in x.args.iter_mut() { + Expr::FnCall(x, ..) => for arg in x.args.iter_mut() { optimize_expr(arg, state, false); // Move constant arguments @@ -1132,15 +1132,15 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { // constant-name #[cfg(not(feature = "no_module"))] - Expr::Variable(_, _, x) if x.1.is_some() => (), - Expr::Variable(_, pos, x) if state.find_constant(&x.2).is_some() => { + Expr::Variable(.., x) if x.1.is_some() => (), + Expr::Variable(.., pos, x) if state.find_constant(&x.2).is_some() => { // Replace constant with value *expr = Expr::from_dynamic(state.find_constant(&x.2).unwrap().clone(), *pos); state.set_dirty(); } // Custom syntax - Expr::Custom(x, _) => { + Expr::Custom(x, ..) => { if x.scope_may_be_changed { state.propagate_constants = false; } diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 6c851dbb..9d7d67b7 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -52,7 +52,7 @@ pub mod array_functions { return Dynamic::UNIT; } - let (index, _) = calc_offset_len(array.len(), index, 0); + let (index, ..) = calc_offset_len(array.len(), index, 0); if index >= array.len() { Dynamic::UNIT @@ -88,7 +88,7 @@ pub mod array_functions { return; } - let (index, _) = calc_offset_len(array.len(), index, 0); + let (index, ..) = calc_offset_len(array.len(), index, 0); if index < array.len() { array[index] = value; @@ -182,7 +182,7 @@ pub mod array_functions { return; } - let (index, _) = calc_offset_len(array.len(), index, 0); + let (index, ..) = calc_offset_len(array.len(), index, 0); if index >= array.len() { array.push(item); @@ -231,10 +231,11 @@ pub mod array_functions { } let check_sizes = match item.0 { - crate::types::dynamic::Union::Array(_, _, _) - | crate::types::dynamic::Union::Str(_, _, _) => true, + crate::types::dynamic::Union::Array(..) | crate::types::dynamic::Union::Str(..) => { + true + } #[cfg(not(feature = "no_object"))] - crate::types::dynamic::Union::Map(_, _, _) => true, + crate::types::dynamic::Union::Map(..) => true, _ => false, }; @@ -651,7 +652,7 @@ pub mod array_functions { mapper .call_raw(&ctx, None, [item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(mapper.fn_name()) => { mapper.call_raw(&ctx, None, [item.clone(), (i as INT).into()]) @@ -740,7 +741,7 @@ pub mod array_functions { if filter .call_raw(&ctx, None, [item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()]) @@ -828,7 +829,7 @@ pub mod array_functions { if ctx .call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => { + ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => { if item.type_id() == value.type_id() { // No default when comparing same type Err(err) @@ -914,13 +915,13 @@ pub mod array_functions { return Ok(-1); } - let (start, _) = calc_offset_len(array.len(), start, 0); + let (start, ..) = calc_offset_len(array.len(), start, 0); for (i, item) in array.iter_mut().enumerate().skip(start) { if ctx .call_fn_raw(OP_EQUALS, true, false, &mut [item, &mut value.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => { + ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => { if item.type_id() == value.type_id() { // No default when comparing same type Err(err) @@ -1044,13 +1045,13 @@ pub mod array_functions { return Ok(-1); } - let (start, _) = calc_offset_len(array.len(), start, 0); + let (start, ..) = calc_offset_len(array.len(), start, 0); for (i, item) in array.iter().enumerate().skip(start) { if filter .call_raw(&ctx, None, [item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()]) @@ -1149,7 +1150,7 @@ pub mod array_functions { if filter .call_raw(&ctx, None, [item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()]) @@ -1236,7 +1237,7 @@ pub mod array_functions { if !filter .call_raw(&ctx, None, [item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()]) @@ -1486,7 +1487,7 @@ pub mod array_functions { result = reducer .call_raw(&ctx, None, [result.clone(), item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(reducer.fn_name()) => { reducer.call_raw(&ctx, None, [result, item, (i as INT).into()]) @@ -1648,7 +1649,7 @@ pub mod array_functions { result = reducer .call_raw(&ctx, None, [result.clone(), item.clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(reducer.fn_name()) => { reducer.call_raw(&ctx, None, [result, item, ((len - 1 - i) as INT).into()]) @@ -1925,7 +1926,7 @@ pub mod array_functions { if filter .call_raw(&ctx, None, [array[x].clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()]) @@ -2121,7 +2122,7 @@ pub mod array_functions { if !filter .call_raw(&ctx, None, [array[x].clone()]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(fn_sig, _) + ERR::ErrorFunctionNotFound(fn_sig, ..) if fn_sig.starts_with(filter.fn_name()) => { filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()]) @@ -2311,7 +2312,7 @@ pub mod array_functions { if !ctx .call_fn_raw(OP_EQUALS, true, false, &mut [a1, a2]) .or_else(|err| match *err { - ERR::ErrorFunctionNotFound(ref fn_sig, _) if fn_sig.starts_with(OP_EQUALS) => { + ERR::ErrorFunctionNotFound(ref fn_sig, ..) if fn_sig.starts_with(OP_EQUALS) => { if a1.type_id() == a2.type_id() { // No default when comparing same type Err(err) diff --git a/src/packages/blob_basic.rs b/src/packages/blob_basic.rs index 007fd1c5..c88dfb16 100644 --- a/src/packages/blob_basic.rs +++ b/src/packages/blob_basic.rs @@ -124,7 +124,7 @@ pub mod blob_functions { return 0; } - let (index, _) = calc_offset_len(blob.len(), index, 0); + let (index, ..) = calc_offset_len(blob.len(), index, 0); if index >= blob.len() { 0 @@ -162,7 +162,7 @@ pub mod blob_functions { return; } - let (index, _) = calc_offset_len(blob.len(), index, 0); + let (index, ..) = calc_offset_len(blob.len(), index, 0); if index < blob.len() { blob[index] = (value & 0x000000ff) as u8; @@ -256,7 +256,7 @@ pub mod blob_functions { return; } - let (index, _) = calc_offset_len(blob.len(), index, 0); + let (index, ..) = calc_offset_len(blob.len(), index, 0); if index >= blob.len() { blob.push(value); diff --git a/src/packages/lang_core.rs b/src/packages/lang_core.rs index cbe6db9c..5e7c5949 100644 --- a/src/packages/lang_core.rs +++ b/src/packages/lang_core.rs @@ -152,7 +152,7 @@ fn collect_fn_metadata( ctx.iter_namespaces() .flat_map(Module::iter_script_fn) .filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f)) - .for_each(|(_, _, _, _, f)| { + .for_each(|(.., f)| { list.push( make_metadata( &dict, @@ -169,7 +169,7 @@ fn collect_fn_metadata( .iter() .flat_map(|m| m.iter_script_fn()) .filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f)) - .for_each(|(_, _, _, _, f)| { + .for_each(|(.., f)| { list.push( make_metadata( &dict, @@ -187,7 +187,7 @@ fn collect_fn_metadata( .values() .flat_map(|m| m.iter_script_fn()) .filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f)) - .for_each(|(_, _, _, _, f)| { + .for_each(|(.., f)| { list.push( make_metadata( &dict, @@ -219,7 +219,7 @@ fn collect_fn_metadata( module .iter_script_fn() .filter(|(s, a, n, p, f)| filter(*s, *a, n, *p, f)) - .for_each(|(_, _, _, _, f)| { + .for_each(|(.., f)| { list.push(make_metadata(dict, Some(namespace.clone()), f).into()) }); for (ns, m) in module.iter_sub_modules() { diff --git a/src/parser.rs b/src/parser.rs index c7346f05..df637d7a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -115,7 +115,7 @@ impl<'e> ParseState<'e> { .iter() .rev() .enumerate() - .find(|(_, (n, _))| { + .find(|(.., (n, ..))| { if n == SCOPE_SEARCH_BARRIER_MARKER { // Do not go beyond the barrier barrier = true; @@ -124,7 +124,7 @@ impl<'e> ParseState<'e> { n == name } }) - .and_then(|(i, _)| NonZeroUsize::new(i + 1)); + .and_then(|(i, ..)| NonZeroUsize::new(i + 1)); #[cfg(not(feature = "no_closure"))] if self.allow_capture { @@ -163,8 +163,8 @@ impl<'e> ParseState<'e> { .iter() .rev() .enumerate() - .find(|&(_, n)| n == name) - .and_then(|(i, _)| NonZeroUsize::new(i + 1)) + .find(|&(.., n)| n == name) + .and_then(|(i, ..)| NonZeroUsize::new(i + 1)) } /// Get an interned identifier, creating one if it is not yet interned. @@ -268,8 +268,8 @@ impl Expr { fn into_property(self, state: &mut ParseState) -> Self { match self { #[cfg(not(feature = "no_module"))] - Self::Variable(_, _, ref x) if x.1.is_some() => self, - Self::Variable(_, pos, x) => { + Self::Variable(.., ref x) if x.1.is_some() => self, + Self::Variable(.., pos, x) => { let ident = x.2; let getter = state.get_identifier(crate::engine::FN_GET, &ident); let hash_get = calc_fn_hash(&getter, 1); @@ -292,15 +292,15 @@ impl Expr { fn ensure_bool_expr(self) -> ParseResult { let type_name = match self { Expr::Unit(_) => "()", - Expr::DynamicConstant(ref v, _) if !v.is::() => v.type_name(), - Expr::IntegerConstant(_, _) => "a number", + Expr::DynamicConstant(ref v, ..) if !v.is::() => v.type_name(), + Expr::IntegerConstant(..) => "a number", #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(_, _) => "a floating-point number", - Expr::CharConstant(_, _) => "a character", - Expr::StringConstant(_, _) => "a string", - Expr::InterpolatedString(_, _) => "a string", - Expr::Array(_, _) => "an array", - Expr::Map(_, _) => "an object map", + Expr::FloatConstant(..) => "a floating-point number", + Expr::CharConstant(..) => "a character", + Expr::StringConstant(..) => "a string", + Expr::InterpolatedString(..) => "a string", + Expr::Array(..) => "an array", + Expr::Map(..) => "an object map", _ => return Ok(self), }; @@ -313,14 +313,14 @@ impl Expr { fn ensure_iterable(self) -> ParseResult { let type_name = match self { Expr::Unit(_) => "()", - Expr::BoolConstant(_, _) => "a boolean", - Expr::IntegerConstant(_, _) => "a number", + Expr::BoolConstant(..) => "a boolean", + Expr::IntegerConstant(..) => "a number", #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(_, _) => "a floating-point number", - Expr::CharConstant(_, _) => "a character", - Expr::StringConstant(_, _) => "a string", - Expr::InterpolatedString(_, _) => "a string", - Expr::Map(_, _) => "an object map", + Expr::FloatConstant(..) => "a floating-point number", + Expr::CharConstant(..) => "a character", + Expr::StringConstant(..) => "a string", + Expr::InterpolatedString(..) => "a string", + Expr::Map(..) => "an object map", _ => return Ok(self), }; @@ -396,7 +396,7 @@ fn parse_var_name(input: &mut TokenStream) -> ParseResult<(Box, Position)> // Bad identifier (Token::LexError(err), pos) => Err(err.into_err(pos)), // Not a variable name - (_, pos) => Err(PERR::VariableExpected.into_err(pos)), + (.., pos) => Err(PERR::VariableExpected.into_err(pos)), } } @@ -410,7 +410,7 @@ fn parse_symbol(input: &mut TokenStream) -> ParseResult<(Box, Position)> { // Bad identifier (Token::LexError(err), pos) => Err(err.into_err(pos)), // Not a symbol - (_, pos) => Err(PERR::MissingSymbol(String::new()).into_err(pos)), + (.., pos) => Err(PERR::MissingSymbol(String::new()).into_err(pos)), } } @@ -436,11 +436,11 @@ fn parse_paren_expr( match input.next().expect(NEVER_ENDS) { // ( xxx ) - (Token::RightParen, _) => Ok(expr), + (Token::RightParen, ..) => Ok(expr), // ( (Token::LexError(err), pos) => Err(err.into_err(pos)), // ( xxx ??? - (_, pos) => Err(PERR::MissingToken( + (.., pos) => Err(PERR::MissingToken( Token::RightParen.into(), "for a matching ( in this expression".into(), ) @@ -535,13 +535,13 @@ fn parse_fn_call( loop { match input.peek().expect(NEVER_ENDS) { // id(...args, ) - handle trailing comma - (Token::RightParen, _) => (), + (Token::RightParen, ..) => (), _ => args.push(parse_expr(input, state, lib, settings)?), } match input.peek().expect(NEVER_ENDS) { // id(...args) - (Token::RightParen, _) => { + (Token::RightParen, ..) => { eat_token(input, Token::RightParen); #[cfg(not(feature = "no_module"))] @@ -592,7 +592,7 @@ fn parse_fn_call( .into_fn_call_expr(settings.pos)); } // id(...args, - (Token::Comma, _) => { + (Token::Comma, ..) => { eat_token(input, Token::Comma); } // id(...args @@ -606,7 +606,7 @@ fn parse_fn_call( // id(...args (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), // id(...args ??? - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::Comma.into(), format!("to separate the arguments to function call '{}'", id), @@ -636,13 +636,13 @@ fn parse_index_chain( // Check type of indexing - must be integer or string match idx_expr { - Expr::IntegerConstant(_, pos) => match lhs { - Expr::IntegerConstant(_, _) - | Expr::Array(_, _) - | Expr::StringConstant(_, _) - | Expr::InterpolatedString(_, _) => (), + Expr::IntegerConstant(.., pos) => match lhs { + Expr::IntegerConstant(..) + | Expr::Array(..) + | Expr::StringConstant(..) + | Expr::InterpolatedString(..) => (), - Expr::Map(_, _) => { + Expr::Map(..) => { return Err(PERR::MalformedIndexExpr( "Object map access expects string index, not a number".into(), ) @@ -650,17 +650,17 @@ fn parse_index_chain( } #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(_, _) => { + Expr::FloatConstant(..) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), ) .into_err(lhs.start_position())) } - Expr::CharConstant(_, _) - | Expr::And(_, _) - | Expr::Or(_, _) - | Expr::BoolConstant(_, _) + Expr::CharConstant(..) + | Expr::And(..) + | Expr::Or(..) + | Expr::BoolConstant(..) | Expr::Unit(_) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), @@ -672,10 +672,10 @@ fn parse_index_chain( }, // lhs[string] - Expr::StringConstant(_, _) | Expr::InterpolatedString(_, _) => match lhs { - Expr::Map(_, _) => (), + Expr::StringConstant(..) | Expr::InterpolatedString(..) => match lhs { + Expr::Map(..) => (), - Expr::Array(_, _) | Expr::StringConstant(_, _) | Expr::InterpolatedString(_, _) => { + Expr::Array(..) | Expr::StringConstant(..) | Expr::InterpolatedString(..) => { return Err(PERR::MalformedIndexExpr( "Array or string expects numeric index, not a string".into(), ) @@ -683,17 +683,17 @@ fn parse_index_chain( } #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(_, _) => { + Expr::FloatConstant(..) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), ) .into_err(lhs.start_position())) } - Expr::CharConstant(_, _) - | Expr::And(_, _) - | Expr::Or(_, _) - | Expr::BoolConstant(_, _) + Expr::CharConstant(..) + | Expr::And(..) + | Expr::Or(..) + | Expr::BoolConstant(..) | Expr::Unit(_) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), @@ -706,14 +706,14 @@ fn parse_index_chain( // lhs[float] #[cfg(not(feature = "no_float"))] - x @ Expr::FloatConstant(_, _) => { + x @ Expr::FloatConstant(..) => { return Err(PERR::MalformedIndexExpr( "Array access expects integer index, not a float".into(), ) .into_err(x.start_position())) } // lhs[char] - x @ Expr::CharConstant(_, _) => { + x @ Expr::CharConstant(..) => { return Err(PERR::MalformedIndexExpr( "Array access expects integer index, not a character".into(), ) @@ -727,14 +727,14 @@ fn parse_index_chain( .into_err(x.start_position())) } // lhs[??? && ???], lhs[??? || ???] - x @ Expr::And(_, _) | x @ Expr::Or(_, _) => { + x @ Expr::And(..) | x @ Expr::Or(..) => { return Err(PERR::MalformedIndexExpr( "Array access expects integer index, not a boolean".into(), ) .into_err(x.start_position())) } // lhs[true], lhs[false] - x @ Expr::BoolConstant(_, _) => { + x @ Expr::BoolConstant(..) => { return Err(PERR::MalformedIndexExpr( "Array access expects integer index, not a boolean".into(), ) @@ -746,13 +746,13 @@ fn parse_index_chain( // Check if there is a closing bracket match input.peek().expect(NEVER_ENDS) { - (Token::RightBracket, _) => { + (Token::RightBracket, ..) => { eat_token(input, Token::RightBracket); // Any more indexing following? match input.peek().expect(NEVER_ENDS) { // If another indexing level, right-bind it - (Token::LeftBracket, _) => { + (Token::LeftBracket, ..) => { let prev_pos = settings.pos; settings.pos = eat_token(input, Token::LeftBracket); // Recursively parse the indexing chain, right-binding each @@ -774,7 +774,7 @@ fn parse_index_chain( } } (Token::LexError(err), pos) => Err(err.clone().into_err(*pos)), - (_, pos) => Err(PERR::MissingToken( + (.., pos) => Err(PERR::MissingToken( Token::RightBracket.into(), "for a matching [ in this index expression".into(), ) @@ -812,7 +812,7 @@ fn parse_array_literal( } match input.peek().expect(NEVER_ENDS) { - (Token::RightBracket, _) => { + (Token::RightBracket, ..) => { eat_token(input, Token::RightBracket); break; } @@ -829,10 +829,10 @@ fn parse_array_literal( } match input.peek().expect(NEVER_ENDS) { - (Token::Comma, _) => { + (Token::Comma, ..) => { eat_token(input, Token::Comma); } - (Token::RightBracket, _) => (), + (Token::RightBracket, ..) => (), (Token::EOF, pos) => { return Err( PERR::MissingToken(Token::RightBracket.into(), MISSING_RBRACKET.into()) @@ -840,7 +840,7 @@ fn parse_array_literal( ) } (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::Comma.into(), "to separate the items of this array literal".into(), @@ -877,7 +877,7 @@ fn parse_map_literal( const MISSING_RBRACE: &str = "to end this object map literal"; match input.peek().expect(NEVER_ENDS) { - (Token::RightBrace, _) => { + (Token::RightBrace, ..) => { eat_token(input, Token::RightBrace); break; } @@ -892,7 +892,7 @@ fn parse_map_literal( let (name, pos) = match input.next().expect(NEVER_ENDS) { (Token::Identifier(s), pos) | (Token::StringConstant(s), pos) => { - if map.iter().any(|(p, _)| p.name == &*s) { + if map.iter().any(|(p, ..)| p.name == &*s) { return Err(PERR::DuplicatedProperty(s.to_string()).into_err(pos)); } (s, pos) @@ -908,19 +908,19 @@ fn parse_map_literal( .into_err(pos), ); } - (_, pos) if map.is_empty() => { + (.., pos) if map.is_empty() => { return Err( PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into()) .into_err(pos), ); } - (_, pos) => return Err(PERR::PropertyExpected.into_err(pos)), + (.., pos) => return Err(PERR::PropertyExpected.into_err(pos)), }; match input.next().expect(NEVER_ENDS) { - (Token::Colon, _) => (), + (Token::Colon, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::Colon.into(), format!( @@ -947,10 +947,10 @@ fn parse_map_literal( map.push((Ident { name, pos }, expr)); match input.peek().expect(NEVER_ENDS) { - (Token::Comma, _) => { + (Token::Comma, ..) => { eat_token(input, Token::Comma); } - (Token::RightBrace, _) => (), + (Token::RightBrace, ..) => (), (Token::Identifier(_), pos) => { return Err(PERR::MissingToken( Token::Comma.into(), @@ -959,7 +959,7 @@ fn parse_map_literal( .into_err(*pos)) } (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), - (_, pos) => { + (.., pos) => { return Err( PERR::MissingToken(Token::RightBrace.into(), MISSING_RBRACE.into()) .into_err(*pos), @@ -990,9 +990,9 @@ fn parse_switch( let item = parse_expr(input, state, lib, settings.level_up())?; match input.next().expect(NEVER_ENDS) { - (Token::LeftBrace, _) => (), + (Token::LeftBrace, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::LeftBrace.into(), "to start a switch block".into(), @@ -1010,7 +1010,7 @@ fn parse_switch( const MISSING_RBRACE: &str = "to end this switch block"; let (expr, condition) = match input.peek().expect(NEVER_ENDS) { - (Token::RightBrace, _) => { + (Token::RightBrace, ..) => { eat_token(input, Token::RightBrace); break; } @@ -1076,9 +1076,9 @@ fn parse_switch( }; match input.next().expect(NEVER_ENDS) { - (Token::DoubleArrow, _) => (), + (Token::DoubleArrow, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::DoubleArrow.into(), "in this switch case".to_string(), @@ -1129,10 +1129,10 @@ fn parse_switch( }; match input.peek().expect(NEVER_ENDS) { - (Token::Comma, _) => { + (Token::Comma, ..) => { eat_token(input, Token::Comma); } - (Token::RightBrace, _) => (), + (Token::RightBrace, ..) => (), (Token::EOF, pos) => { return Err( PERR::MissingToken(Token::RightParen.into(), MISSING_RBRACE.into()) @@ -1140,14 +1140,14 @@ fn parse_switch( ) } (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), - (_, pos) if need_comma => { + (.., pos) if need_comma => { return Err(PERR::MissingToken( Token::Comma.into(), "to separate the items in this switch block".into(), ) .into_err(*pos)) } - (_, _) => (), + (..) => (), } } @@ -1213,7 +1213,7 @@ fn parse_primary( // { - block statement as expression Token::LeftBrace if settings.allow_stmt_expr => { match parse_block(input, state, lib, settings.level_up())? { - block @ Stmt::Block(_, _) => Expr::Stmt(Box::new(block.into())), + block @ Stmt::Block(..) => Expr::Stmt(Box::new(block.into())), stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), } } @@ -1296,7 +1296,7 @@ fn parse_primary( loop { let expr = match parse_block(input, state, lib, settings.level_up())? { - block @ Stmt::Block(_, _) => Expr::Stmt(Box::new(block.into())), + block @ Stmt::Block(..) => Expr::Stmt(Box::new(block.into())), stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), }; segments.push(expr); @@ -1322,7 +1322,7 @@ fn parse_primary( (Token::LexError(err @ LexError::UnterminatedString), pos) => { return Err(err.into_err(pos)) } - (token, _) => unreachable!( + (token, ..) => unreachable!( "string within an interpolated string literal expected but gets {:?}", token ), @@ -1346,7 +1346,7 @@ fn parse_primary( if state.engine.custom_syntax.contains_key(&**key) => { let (key, syntax) = state.engine.custom_syntax.get_key_value(&**key).unwrap(); - let (_, pos) = input.next().expect(NEVER_ENDS); + let (.., pos) = input.next().expect(NEVER_ENDS); let settings2 = settings.level_up(); parse_custom_syntax(input, state, lib, settings2, key, syntax, pos)? } @@ -1359,7 +1359,7 @@ fn parse_primary( let none = (); let s = match input.next().expect(NEVER_ENDS) { - (Token::Identifier(s), _) => s, + (Token::Identifier(s), ..) => s, token => unreachable!("Token::Identifier expected but gets {:?}", token), }; @@ -1423,7 +1423,7 @@ fn parse_primary( let none = (); let s = match input.next().expect(NEVER_ENDS) { - (Token::Reserved(s), _) => s, + (Token::Reserved(s), ..) => s, token => unreachable!("Token::Reserved expected but gets {:?}", token), }; @@ -1451,7 +1451,7 @@ fn parse_primary( } Token::LexError(_) => match input.next().expect(NEVER_ENDS) { - (Token::LexError(err), _) => return Err(err.into_err(settings.pos)), + (Token::LexError(err), ..) => return Err(err.into_err(settings.pos)), token => unreachable!("Token::LexError expected but gets {:?}", token), }, @@ -1475,7 +1475,7 @@ fn parse_postfix( // Tail processing all possible postfix operators loop { - let (tail_token, _) = input.peek().expect(NEVER_ENDS); + let (tail_token, ..) = input.peek().expect(NEVER_ENDS); if !lhs.is_valid_postfix(tail_token) { break; @@ -1487,7 +1487,7 @@ fn parse_postfix( lhs = match (lhs, tail_token) { // Qualified function call with ! #[cfg(not(feature = "no_module"))] - (Expr::Variable(_, _, x), Token::Bang) if x.1.is_some() => { + (Expr::Variable(.., x), Token::Bang) if x.1.is_some() => { return if !match_token(input, Token::LeftParen).0 { Err(LexError::UnexpectedInput(Token::Bang.syntax().to_string()) .into_err(tail_pos)) @@ -1500,7 +1500,7 @@ fn parse_postfix( }; } // Function call with ! - (Expr::Variable(_, pos, x), Token::Bang) => { + (Expr::Variable(.., pos, x), Token::Bang) => { match match_token(input, Token::LeftParen) { (false, pos) => { return Err(PERR::MissingToken( @@ -1512,10 +1512,10 @@ fn parse_postfix( _ => (), } - let (_, _ns, name) = *x; + let (.., _ns, name) = *x; settings.pos = pos; #[cfg(not(feature = "no_module"))] - let _ns = _ns.map(|(ns, _)| ns); + let _ns = _ns.map(|(ns, ..)| ns); parse_fn_call( input, state, @@ -1528,10 +1528,10 @@ fn parse_postfix( )? } // Function call - (Expr::Variable(_, pos, x), Token::LeftParen) => { - let (_, _ns, name) = *x; + (Expr::Variable(.., pos, x), Token::LeftParen) => { + let (.., _ns, name) = *x; #[cfg(not(feature = "no_module"))] - let _ns = _ns.map(|(ns, _)| ns); + let _ns = _ns.map(|(ns, ..)| ns); settings.pos = pos; parse_fn_call( input, @@ -1546,12 +1546,12 @@ fn parse_postfix( } // module access #[cfg(not(feature = "no_module"))] - (Expr::Variable(_, pos, x), Token::DoubleColon) => { + (Expr::Variable(.., pos, x), Token::DoubleColon) => { let (id2, pos2) = parse_var_name(input)?; - let (_, mut namespace, name) = *x; + let (.., mut namespace, name) = *x; let var_name_def = Ident { name, pos }; - if let Some((ref mut namespace, _)) = namespace { + if let Some((ref mut namespace, ..)) = namespace { namespace.push(var_name_def); } else { let mut ns = crate::module::Namespace::new(); @@ -1575,15 +1575,15 @@ fn parse_postfix( (expr, Token::Period) => { // Expression after dot must start with an identifier match input.peek().expect(NEVER_ENDS) { - (Token::Identifier(_), _) => { + (Token::Identifier(_), ..) => { #[cfg(not(feature = "no_closure"))] { // Prevents capturing of the object properties as vars: xxx. state.allow_capture = false; } } - (Token::Reserved(s), _) if is_keyword_function(s) => (), - (_, pos) => return Err(PERR::PropertyExpected.into_err(*pos)), + (Token::Reserved(s), ..) if is_keyword_function(s) => (), + (.., pos) => return Err(PERR::PropertyExpected.into_err(*pos)), } let rhs = parse_primary(input, state, lib, settings.level_up())?; @@ -1601,16 +1601,16 @@ fn parse_postfix( // Cache the hash key for namespace-qualified variables #[cfg(not(feature = "no_module"))] let namespaced_variable = match lhs { - Expr::Variable(_, _, ref mut x) if x.1.is_some() => Some(x.as_mut()), - Expr::Index(ref mut x, _, _) | Expr::Dot(ref mut x, _, _) => match x.lhs { - Expr::Variable(_, _, ref mut x) if x.1.is_some() => Some(x.as_mut()), + Expr::Variable(.., ref mut x) if x.1.is_some() => Some(x.as_mut()), + Expr::Index(ref mut x, ..) | Expr::Dot(ref mut x, ..) => match x.lhs { + Expr::Variable(.., ref mut x) if x.1.is_some() => Some(x.as_mut()), _ => None, }, _ => None, }; #[cfg(not(feature = "no_module"))] - if let Some((_, Some((namespace, hash)), name)) = namespaced_variable { + if let Some((.., Some((namespace, hash)), name)) = namespaced_variable { *hash = crate::calc_qualified_var_hash(namespace.iter().map(|v| v.name.as_str()), name); #[cfg(not(feature = "no_module"))] @@ -1659,7 +1659,7 @@ fn parse_unary( match parse_unary(input, state, lib, settings.level_up())? { // Negative integer - Expr::IntegerConstant(num, _) => num + Expr::IntegerConstant(num, ..) => num .checked_neg() .map(|i| Expr::IntegerConstant(i, pos)) .or_else(|| { @@ -1672,7 +1672,7 @@ fn parse_unary( // Negative float #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(x, _) => Ok(Expr::FloatConstant((-(*x)).into(), pos)), + Expr::FloatConstant(x, ..) => Ok(Expr::FloatConstant((-(*x)).into(), pos)), // Call negative function expr => { @@ -1697,9 +1697,9 @@ fn parse_unary( let pos = eat_token(input, token); match parse_unary(input, state, lib, settings.level_up())? { - expr @ Expr::IntegerConstant(_, _) => Ok(expr), + expr @ Expr::IntegerConstant(..) => Ok(expr), #[cfg(not(feature = "no_float"))] - expr @ Expr::FloatConstant(_, _) => Ok(expr), + expr @ Expr::FloatConstant(..) => Ok(expr), // Call plus function expr => { @@ -1752,21 +1752,19 @@ fn make_assignment_stmt( #[must_use] fn check_lvalue(expr: &Expr, parent_is_dot: bool) -> Option { match expr { - Expr::Index(x, term, _) | Expr::Dot(x, term, _) if parent_is_dot => match x.lhs { - Expr::Property(_, _) if !term => { - check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))) - } - Expr::Property(_, _) => None, + Expr::Index(x, term, ..) | Expr::Dot(x, term, ..) if parent_is_dot => match x.lhs { + Expr::Property(..) if !term => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(..))), + Expr::Property(..) => None, // Anything other than a property after dotting (e.g. a method call) is not an l-value ref e => Some(e.position()), }, - Expr::Index(x, term, _) | Expr::Dot(x, term, _) => match x.lhs { - Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"), - _ if !term => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))), + Expr::Index(x, term, ..) | Expr::Dot(x, term, ..) => match x.lhs { + Expr::Property(..) => unreachable!("unexpected Expr::Property in indexing"), + _ if !term => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(..))), _ => None, }, - Expr::Property(_, _) if parent_is_dot => None, - Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"), + Expr::Property(..) if parent_is_dot => None, + Expr::Property(..) => unreachable!("unexpected Expr::Property in indexing"), e if parent_is_dot => Some(e.position()), _ => None, } @@ -1803,18 +1801,18 @@ fn make_assignment_stmt( } } // xxx[???]... = rhs, xxx.prop... = rhs - Expr::Index(ref x, term, _) | Expr::Dot(ref x, term, _) => { + Expr::Index(ref x, term, ..) | Expr::Dot(ref x, term, ..) => { let valid_lvalue = if term { None } else { - check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(_, _, _))) + check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(..))) }; match valid_lvalue { None => { match x.lhs { // var[???] = rhs, var.??? = rhs - Expr::Variable(_, _, _) => Ok(Stmt::Assignment( + Expr::Variable(..) => Ok(Stmt::Assignment( (op_info, (lhs, rhs).into()).into(), op_pos, )), @@ -1831,7 +1829,7 @@ fn make_assignment_stmt( } } // ??? && ??? = rhs, ??? || ??? = rhs - Expr::And(_, _) | Expr::Or(_, _) => Err(LexError::ImproperSymbol( + Expr::And(..) | Expr::Or(..) => Err(LexError::ImproperSymbol( "=".to_string(), "Possibly a typo of '=='?".to_string(), ) @@ -1854,9 +1852,9 @@ fn parse_op_assignment_stmt( let (op, pos) = match input.peek().expect(NEVER_ENDS) { // var = ... - (Token::Equals, _) => (None, eat_token(input, Token::Equals)), + (Token::Equals, ..) => (None, eat_token(input, Token::Equals)), // var op= ... - (token, _) if token.is_op_assignment() => input + (token, ..) if token.is_op_assignment() => input .next() .map(|(op, pos)| (Some(op), pos)) .expect(NEVER_ENDS), @@ -1887,25 +1885,25 @@ fn make_dot_expr( Ok(Expr::Index(x, false, pos)) } // lhs.id - (lhs, var_expr @ Expr::Variable(_, _, _)) if var_expr.is_variable_access(true) => { + (lhs, var_expr @ Expr::Variable(..)) if var_expr.is_variable_access(true) => { let rhs = var_expr.into_property(state); Ok(Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos)) } // lhs.module::id - syntax error #[cfg(not(feature = "no_module"))] - (_, Expr::Variable(_, _, x)) => { + (.., Expr::Variable(.., x)) => { Err(PERR::PropertyExpected.into_err(x.1.expect("`Some`").0[0].pos)) } #[cfg(feature = "no_module")] - (_, Expr::Variable(_, _, _)) => unreachable!("qualified property name"), + (.., Expr::Variable(..)) => unreachable!("qualified property name"), // lhs.prop - (lhs, prop @ Expr::Property(_, _)) => Ok(Expr::Dot( + (lhs, prop @ Expr::Property(..)) => Ok(Expr::Dot( BinaryExpr { lhs, rhs: prop }.into(), false, op_pos, )), // lhs.dot_lhs.dot_rhs or lhs.dot_lhs[idx_rhs] - (lhs, rhs @ Expr::Dot(_, _, _)) | (lhs, rhs @ Expr::Index(_, _, _)) => { + (lhs, rhs @ Expr::Dot(..)) | (lhs, rhs @ Expr::Index(..)) => { let (x, term, pos, is_dot) = match rhs { Expr::Dot(x, term, pos) => (x, term, pos, true), Expr::Index(x, term, pos) => (x, term, pos, false), @@ -1913,7 +1911,7 @@ fn make_dot_expr( }; match x.lhs { - Expr::Variable(_, _, _) | Expr::Property(_, _) => { + Expr::Variable(..) | Expr::Property(..) => { let new_lhs = BinaryExpr { lhs: x.lhs.into_property(state), rhs: x.rhs, @@ -1952,11 +1950,11 @@ fn make_dot_expr( } } // lhs.nnn::func(...) - (_, Expr::FnCall(x, _)) if x.is_qualified() => { + (.., Expr::FnCall(x, ..)) if x.is_qualified() => { unreachable!("method call should not be namespace-qualified") } // lhs.Fn() or lhs.eval() - (_, Expr::FnCall(x, pos)) + (.., Expr::FnCall(x, pos)) if x.args.is_empty() && [crate::engine::KEYWORD_FN_PTR, crate::engine::KEYWORD_EVAL] .contains(&x.name.as_ref()) => @@ -1971,7 +1969,7 @@ fn make_dot_expr( .into_err(pos)) } // lhs.func!(...) - (_, Expr::FnCall(x, pos)) if x.capture_parent_scope => Err(PERR::MalformedCapture( + (.., Expr::FnCall(x, pos)) if x.capture_parent_scope => Err(PERR::MalformedCapture( "method-call style does not support running within the caller's scope".into(), ) .into_err(pos)), @@ -1988,7 +1986,7 @@ fn make_dot_expr( Ok(Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos)) } // lhs.rhs - (_, rhs) => Err(PERR::PropertyExpected.into_err(rhs.start_position())), + (.., rhs) => Err(PERR::PropertyExpected.into_err(rhs.start_position())), } } @@ -2248,7 +2246,7 @@ fn parse_custom_syntax( tokens.push(keyword); } CUSTOM_SYNTAX_MARKER_BLOCK => match parse_block(input, state, lib, settings)? { - block @ Stmt::Block(_, _) => { + block @ Stmt::Block(..) => { inputs.push(Expr::Stmt(Box::new(block.into()))); let keyword = state.get_identifier("", CUSTOM_SYNTAX_MARKER_BLOCK); segments.push(keyword.clone().into()); @@ -2262,7 +2260,7 @@ fn parse_custom_syntax( segments.push(state.get_interned_string("", b.literal_syntax())); tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_BOOL)); } - (_, pos) => { + (.., pos) => { return Err( PERR::MissingSymbol("Expecting 'true' or 'false'".to_string()) .into_err(pos), @@ -2275,7 +2273,7 @@ fn parse_custom_syntax( segments.push(i.to_string().into()); tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_INT)); } - (_, pos) => { + (.., pos) => { return Err( PERR::MissingSymbol("Expecting an integer number".to_string()) .into_err(pos), @@ -2289,7 +2287,7 @@ fn parse_custom_syntax( segments.push(f.to_string().into()); tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_FLOAT)); } - (_, pos) => { + (.., pos) => { return Err(PERR::MissingSymbol( "Expecting a floating-point number".to_string(), ) @@ -2303,17 +2301,17 @@ fn parse_custom_syntax( segments.push(s); tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_STRING)); } - (_, pos) => { + (.., pos) => { return Err(PERR::MissingSymbol("Expecting a string".to_string()).into_err(pos)) } }, s => match input.next().expect(NEVER_ENDS) { (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (t, _) if &*t.syntax() == s => { + (t, ..) if &*t.syntax() == s => { segments.push(required_token.clone()); tokens.push(required_token.clone().into()); } - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( s.to_string(), format!("for '{}' expression", segments[0]), @@ -2391,7 +2389,7 @@ fn parse_if( // if guard { if_body } else ... let else_body = if match_token(input, Token::Else).0 { - if let (Token::If, _) = input.peek().expect(NEVER_ENDS) { + if let (Token::If, ..) = input.peek().expect(NEVER_ENDS) { // if guard { if_body } else if ... parse_if(input, state, lib, settings.level_up())? } else { @@ -2459,9 +2457,9 @@ fn parse_do( let body = parse_block(input, state, lib, settings.level_up())?; let negated = match input.next().expect(NEVER_ENDS) { - (Token::While, _) => AST_OPTION_NONE, - (Token::Until, _) => AST_OPTION_NEGATED, - (_, pos) => { + (Token::While, ..) => AST_OPTION_NONE, + (Token::Until, ..) => AST_OPTION_NEGATED, + (.., pos) => { return Err( PERR::MissingToken(Token::While.into(), "for the do statement".into()) .into_err(pos), @@ -2532,9 +2530,9 @@ fn parse_for( // for name in ... match input.next().expect(NEVER_ENDS) { - (Token::In, _) => (), + (Token::In, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err( PERR::MissingToken(Token::In.into(), "after the iteration variable".into()) .into_err(pos), @@ -2594,7 +2592,7 @@ fn parse_let( let (name, pos) = parse_var_name(input)?; if !settings.default_options.allow_shadowing - && state.stack.iter().any(|(v, _)| v == name.as_ref()) + && state.stack.iter().any(|(v, ..)| v == name.as_ref()) { return Err(PERR::VariableExists(name.to_string()).into_err(pos)); } @@ -2737,7 +2735,7 @@ fn parse_block( settings.pos = match input.next().expect(NEVER_ENDS) { (Token::LeftBrace, pos) => pos, (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::LeftBrace.into(), "to start a statement block".into(), @@ -2757,7 +2755,7 @@ fn parse_block( let end_pos = loop { // Terminated? match input.peek().expect(NEVER_ENDS) { - (Token::RightBrace, _) => break eat_token(input, Token::RightBrace), + (Token::RightBrace, ..) => break eat_token(input, Token::RightBrace), (Token::EOF, pos) => { return Err(PERR::MissingToken( Token::RightBrace.into(), @@ -2784,21 +2782,21 @@ fn parse_block( match input.peek().expect(NEVER_ENDS) { // { ... stmt } - (Token::RightBrace, _) => break eat_token(input, Token::RightBrace), + (Token::RightBrace, ..) => break eat_token(input, Token::RightBrace), // { ... stmt; - (Token::SemiColon, _) if need_semicolon => { + (Token::SemiColon, ..) if need_semicolon => { eat_token(input, Token::SemiColon); } // { ... { stmt } ; - (Token::SemiColon, _) if !need_semicolon => { + (Token::SemiColon, ..) if !need_semicolon => { eat_token(input, Token::SemiColon); } // { ... { stmt } ??? - (_, _) if !need_semicolon => (), + (..) if !need_semicolon => (), // { ... stmt (Token::LexError(err), err_pos) => return Err(err.clone().into_err(*err_pos)), // { ... stmt ??? - (_, pos) => { + (.., pos) => { // Semicolons are not optional between statements return Err(PERR::MissingToken( Token::SemiColon.into(), @@ -2875,8 +2873,8 @@ fn parse_stmt( comments.push(comment); match input.peek().expect(NEVER_ENDS) { - (Token::Fn, _) | (Token::Private, _) => break, - (Token::Comment(_), _) => (), + (Token::Fn, ..) | (Token::Private, ..) => break, + (Token::Comment(_), ..) => (), _ => return Err(PERR::WrongDocComment.into_err(comments_pos)), } } @@ -2971,7 +2969,7 @@ fn parse_stmt( Ok(Stmt::Noop(pos)) } - (_, pos) => Err(PERR::MissingToken( + (.., pos) => Err(PERR::MissingToken( Token::Fn.into(), format!("following '{}'", Token::Private.syntax()), ) @@ -3021,15 +3019,15 @@ fn parse_stmt( match input.peek().expect(NEVER_ENDS) { // `return`/`throw` at - (Token::EOF, _) => Ok(Stmt::Return(return_type, None, token_pos)), + (Token::EOF, ..) => Ok(Stmt::Return(return_type, None, token_pos)), // `return`/`throw` at end of block - (Token::RightBrace, _) if !settings.is_global => { + (Token::RightBrace, ..) if !settings.is_global => { Ok(Stmt::Return(return_type, None, token_pos)) } // `return;` or `throw;` - (Token::SemiColon, _) => Ok(Stmt::Return(return_type, None, token_pos)), + (Token::SemiColon, ..) => Ok(Stmt::Return(return_type, None, token_pos)), // `return` or `throw` with expression - (_, _) => { + (..) => { let expr = parse_expr(input, state, lib, settings.level_up())?; Ok(Stmt::Return(return_type, Some(expr), token_pos)) } @@ -3146,8 +3144,8 @@ fn parse_fn( }; match input.peek().expect(NEVER_ENDS) { - (Token::LeftParen, _) => eat_token(input, Token::LeftParen), - (_, pos) => return Err(PERR::FnMissingParams(name.to_string()).into_err(*pos)), + (Token::LeftParen, ..) => eat_token(input, Token::LeftParen), + (.., pos) => return Err(PERR::FnMissingParams(name.to_string()).into_err(*pos)), }; let mut params = StaticVec::new_const(); @@ -3157,7 +3155,7 @@ fn parse_fn( loop { match input.next().expect(NEVER_ENDS) { - (Token::RightParen, _) => break, + (Token::RightParen, ..) => break, (Token::Identifier(s), pos) => { if params.iter().any(|(p, _)| p == &*s) { return Err( @@ -3169,7 +3167,7 @@ fn parse_fn( params.push((s, pos)) } (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::RightParen.into(), format!("to close the parameters list of function '{}'", name), @@ -3179,10 +3177,10 @@ fn parse_fn( } match input.next().expect(NEVER_ENDS) { - (Token::RightParen, _) => break, - (Token::Comma, _) => (), + (Token::RightParen, ..) => break, + (Token::Comma, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken(Token::Comma.into(), sep_err).into_err(pos)) } } @@ -3191,15 +3189,15 @@ fn parse_fn( // Parse function body let body = match input.peek().expect(NEVER_ENDS) { - (Token::LeftBrace, _) => { + (Token::LeftBrace, ..) => { settings.is_breakable = false; parse_block(input, state, lib, settings.level_up())? } - (_, pos) => return Err(PERR::FnMissingBody(name.to_string()).into_err(*pos)), + (.., pos) => return Err(PERR::FnMissingBody(name.to_string()).into_err(*pos)), } .into(); - let mut params: StaticVec<_> = params.into_iter().map(|(p, _)| p).collect(); + let mut params: StaticVec<_> = params.into_iter().map(|(p, ..)| p).collect(); params.shrink_to_fit(); Ok(ScriptFnDef { @@ -3291,7 +3289,7 @@ fn parse_anon_fn( if input.next().expect(NEVER_ENDS).0 != Token::Or && !match_token(input, Token::Pipe).0 { loop { match input.next().expect(NEVER_ENDS) { - (Token::Pipe, _) => break, + (Token::Pipe, ..) => break, (Token::Identifier(s), pos) => { if params_list.iter().any(|p| p == &*s) { return Err( @@ -3303,7 +3301,7 @@ fn parse_anon_fn( params_list.push(s) } (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::Pipe.into(), "to close the parameters list of anonymous function".into(), @@ -3313,10 +3311,10 @@ fn parse_anon_fn( } match input.next().expect(NEVER_ENDS) { - (Token::Pipe, _) => break, - (Token::Comma, _) => (), + (Token::Pipe, ..) => break, + (Token::Comma, ..) => (), (Token::LexError(err), pos) => return Err(err.into_err(pos)), - (_, pos) => { + (.., pos) => { return Err(PERR::MissingToken( Token::Comma.into(), "to separate the parameters of anonymous function".into(), @@ -3416,7 +3414,7 @@ impl Engine { assert!(functions.is_empty()); match input.peek().expect(NEVER_ENDS) { - (Token::EOF, _) => (), + (Token::EOF, ..) => (), // Return error if the expression doesn't end (token, pos) => { return Err(LexError::UnexpectedInput(token.syntax().to_string()).into_err(*pos)) @@ -3485,19 +3483,19 @@ impl Engine { match input.peek().expect(NEVER_ENDS) { // EOF - (Token::EOF, _) => break, + (Token::EOF, ..) => break, // stmt ; - (Token::SemiColon, _) if need_semicolon => { + (Token::SemiColon, ..) if need_semicolon => { eat_token(input, Token::SemiColon); } // stmt ; - (Token::SemiColon, _) if !need_semicolon => (), + (Token::SemiColon, ..) if !need_semicolon => (), // { stmt } ??? - (_, _) if !need_semicolon => (), + (..) if !need_semicolon => (), // stmt (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), // stmt ??? - (_, pos) => { + (.., pos) => { // Semicolons are not optional between statements return Err(PERR::MissingToken( Token::SemiColon.into(), @@ -3508,7 +3506,7 @@ impl Engine { } } - Ok((statements, functions.into_iter().map(|(_, v)| v).collect())) + Ok((statements, functions.into_iter().map(|(.., v)| v).collect())) } /// Run the parser on an input stream, returning an AST. diff --git a/src/serde/de.rs b/src/serde/de.rs index eb158707..cf3e638a 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -118,55 +118,55 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { fn deserialize_any>(self, visitor: V) -> RhaiResultOf { match self.value.0 { - Union::Unit(_, _, _) => self.deserialize_unit(visitor), - Union::Bool(_, _, _) => self.deserialize_bool(visitor), - Union::Str(_, _, _) => self.deserialize_str(visitor), - Union::Char(_, _, _) => self.deserialize_char(visitor), + Union::Unit(..) => self.deserialize_unit(visitor), + Union::Bool(..) => self.deserialize_bool(visitor), + Union::Str(..) => self.deserialize_str(visitor), + Union::Char(..) => self.deserialize_char(visitor), #[cfg(not(feature = "only_i32"))] - Union::Int(_, _, _) => self.deserialize_i64(visitor), + Union::Int(..) => self.deserialize_i64(visitor), #[cfg(feature = "only_i32")] - Union::Int(_, _, _) => self.deserialize_i32(visitor), + Union::Int(..) => self.deserialize_i32(visitor), #[cfg(not(feature = "no_float"))] #[cfg(not(feature = "f32_float"))] - Union::Float(_, _, _) => self.deserialize_f64(visitor), + Union::Float(..) => self.deserialize_f64(visitor), #[cfg(not(feature = "no_float"))] #[cfg(feature = "f32_float")] - Union::Float(_, _, _) => self.deserialize_f32(visitor), + Union::Float(..) => self.deserialize_f32(visitor), #[cfg(feature = "decimal")] #[cfg(not(feature = "f32_float"))] - Union::Decimal(_, _, _) => self.deserialize_f64(visitor), + Union::Decimal(..) => self.deserialize_f64(visitor), #[cfg(feature = "decimal")] #[cfg(feature = "f32_float")] - Union::Decimal(_, _, _) => self.deserialize_f32(visitor), + Union::Decimal(..) => self.deserialize_f32(visitor), #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => self.deserialize_seq(visitor), + Union::Array(..) => self.deserialize_seq(visitor), #[cfg(not(feature = "no_index"))] - Union::Blob(_, _, _) => self.deserialize_bytes(visitor), + Union::Blob(..) => self.deserialize_bytes(visitor), #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => self.deserialize_map(visitor), - Union::FnPtr(_, _, _) => self.type_error(), + Union::Map(..) => self.deserialize_map(visitor), + Union::FnPtr(..) => self.type_error(), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => self.type_error(), + Union::TimeStamp(..) => self.type_error(), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_i8(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_i16(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_i32(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_i64(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_i128(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_u8(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_u16(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_u32(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_u64(visitor), - Union::Variant(ref value, _, _) if value.is::() => self.deserialize_u128(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_i8(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_i16(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_i32(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_i64(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_i128(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_u8(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_u16(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_u32(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_u64(visitor), + Union::Variant(ref value, ..) if value.is::() => self.deserialize_u128(visitor), - Union::Variant(_, _, _) => self.type_error(), + Union::Variant(..) => self.type_error(), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.type_error(), + Union::Shared(..) => self.type_error(), } } diff --git a/src/serde/serialize.rs b/src/serde/serialize.rs index daf0fd32..579f0d1e 100644 --- a/src/serde/serialize.rs +++ b/src/serde/serialize.rs @@ -15,26 +15,26 @@ use crate::types::dynamic::Variant; impl Serialize for Dynamic { fn serialize(&self, ser: S) -> Result { match self.0 { - Union::Unit(_, _, _) => ser.serialize_unit(), - Union::Bool(x, _, _) => ser.serialize_bool(x), - Union::Str(ref s, _, _) => ser.serialize_str(s.as_str()), - Union::Char(c, _, _) => ser.serialize_str(&c.to_string()), + Union::Unit(..) => ser.serialize_unit(), + Union::Bool(x, ..) => ser.serialize_bool(x), + Union::Str(ref s, ..) => ser.serialize_str(s.as_str()), + Union::Char(c, ..) => ser.serialize_str(&c.to_string()), #[cfg(not(feature = "only_i32"))] - Union::Int(x, _, _) => ser.serialize_i64(x), + Union::Int(x, ..) => ser.serialize_i64(x), #[cfg(feature = "only_i32")] - Union::Int(x, _, _) => ser.serialize_i32(x), + Union::Int(x, ..) => ser.serialize_i32(x), #[cfg(not(feature = "no_float"))] #[cfg(not(feature = "f32_float"))] - Union::Float(x, _, _) => ser.serialize_f64(*x), + Union::Float(x, ..) => ser.serialize_f64(*x), #[cfg(not(feature = "no_float"))] #[cfg(feature = "f32_float")] - Union::Float(x, _, _) => ser.serialize_f32(*x), + Union::Float(x, ..) => ser.serialize_f32(*x), #[cfg(feature = "decimal")] #[cfg(not(feature = "f32_float"))] - Union::Decimal(ref x, _, _) => { + Union::Decimal(ref x, ..) => { use rust_decimal::prelude::ToPrimitive; if let Some(v) = x.to_f64() { @@ -45,7 +45,7 @@ impl Serialize for Dynamic { } #[cfg(feature = "decimal")] #[cfg(feature = "f32_float")] - Union::Decimal(ref x, _, _) => { + Union::Decimal(ref x, ..) => { use rust_decimal::prelude::ToPrimitive; if let Some(v) = x.to_f32() { @@ -56,28 +56,28 @@ impl Serialize for Dynamic { } #[cfg(not(feature = "no_index"))] - Union::Array(ref a, _, _) => (**a).serialize(ser), + Union::Array(ref a, ..) => (**a).serialize(ser), #[cfg(not(feature = "no_index"))] - Union::Blob(ref a, _, _) => (**a).serialize(ser), + Union::Blob(ref a, ..) => (**a).serialize(ser), #[cfg(not(feature = "no_object"))] - Union::Map(ref m, _, _) => { + Union::Map(ref m, ..) => { let mut map = ser.serialize_map(Some(m.len()))?; m.iter() .try_for_each(|(k, v)| map.serialize_entry(k.as_str(), v))?; map.end() } - Union::FnPtr(ref f, _, _) => ser.serialize_str(f.fn_name()), + Union::FnPtr(ref f, ..) => ser.serialize_str(f.fn_name()), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(ref x, _, _) => ser.serialize_str(x.as_ref().type_name()), + Union::TimeStamp(ref x, ..) => ser.serialize_str(x.as_ref().type_name()), - Union::Variant(ref v, _, _) => ser.serialize_str((***v).type_name()), + Union::Variant(ref v, ..) => ser.serialize_str((***v).type_name()), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => cell.borrow().serialize(ser), + Union::Shared(ref cell, ..) => cell.borrow().serialize(ser), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => cell.read().unwrap().serialize(ser), + Union::Shared(ref cell, ..) => cell.read().unwrap().serialize(ser), } } } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index d4202b18..e1b2081b 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1332,7 +1332,7 @@ pub fn get_next_token( let result = get_next_token_inner(stream, state, pos); // Save the last token's state - if let Some((ref token, _)) = result { + if let Some((ref token, ..)) = result { state.next_token_cannot_be_unary = !token.is_next_unary(); } @@ -1420,10 +1420,10 @@ fn get_next_token_inner( match (c, stream.peek_next().unwrap_or('\0')) { // \n - ('\n', _) => pos.new_line(), + ('\n', ..) => pos.new_line(), // digit ... - ('0'..='9', _) => { + ('0'..='9', ..) => { let mut result = smallvec::SmallVec::<[char; 16]>::new(); let mut radix_base: Option = None; let mut valid: fn(char) -> bool = is_numeric_digit; @@ -1573,24 +1573,24 @@ fn get_next_token_inner( // letter or underscore ... #[cfg(not(feature = "unicode-xid-ident"))] - ('a'..='z', _) | ('_', _) | ('A'..='Z', _) => { + ('a'..='z', ..) | ('_', ..) | ('A'..='Z', ..) => { return get_identifier(stream, pos, start_pos, c); } #[cfg(feature = "unicode-xid-ident")] - (ch, _) if unicode_xid::UnicodeXID::is_xid_start(ch) || ch == '_' => { + (ch, ..) if unicode_xid::UnicodeXID::is_xid_start(ch) || ch == '_' => { return get_identifier(stream, pos, start_pos, c); } // " - string literal - ('"', _) => { + ('"', ..) => { return parse_string_literal(stream, state, pos, c, false, true, false) .map_or_else( |(err, err_pos)| Some((Token::LexError(err), err_pos)), - |(result, _)| Some((Token::StringConstant(result), start_pos)), + |(result, ..)| Some((Token::StringConstant(result), start_pos)), ); } // ` - string literal - ('`', _) => { + ('`', ..) => { // Start from the next line if at the end of line match stream.peek_next() { // `\r - start from next line @@ -1629,11 +1629,11 @@ fn get_next_token_inner( start_pos, )) } - ('\'', _) => { + ('\'', ..) => { return Some( parse_string_literal(stream, state, pos, c, false, false, false).map_or_else( |(err, err_pos)| (Token::LexError(err), err_pos), - |(result, _)| { + |(result, ..)| { let mut chars = result.chars(); let first = chars.next().unwrap(); @@ -1651,20 +1651,20 @@ fn get_next_token_inner( } // Braces - ('{', _) => return Some((Token::LeftBrace, start_pos)), - ('}', _) => return Some((Token::RightBrace, start_pos)), + ('{', ..) => return Some((Token::LeftBrace, start_pos)), + ('}', ..) => return Some((Token::RightBrace, start_pos)), // Parentheses ('(', '*') => { eat_next(stream, pos); return Some((Token::Reserved("(*".into()), start_pos)); } - ('(', _) => return Some((Token::LeftParen, start_pos)), - (')', _) => return Some((Token::RightParen, start_pos)), + ('(', ..) => return Some((Token::LeftParen, start_pos)), + (')', ..) => return Some((Token::RightParen, start_pos)), // Indexing - ('[', _) => return Some((Token::LeftBracket, start_pos)), - (']', _) => return Some((Token::RightBracket, start_pos)), + ('[', ..) => return Some((Token::LeftBracket, start_pos)), + (']', ..) => return Some((Token::RightBracket, start_pos)), // Map literal #[cfg(not(feature = "no_object"))] @@ -1686,7 +1686,7 @@ fn get_next_token_inner( return Some((Token::Reserved(token.into()), start_pos)); } - ('#', _) => return Some((Token::Reserved("#".into()), start_pos)), + ('#', ..) => return Some((Token::Reserved("#".into()), start_pos)), // Operators ('+', '=') => { @@ -1697,10 +1697,10 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::Reserved("++".into()), start_pos)); } - ('+', _) if !state.next_token_cannot_be_unary => { + ('+', ..) if !state.next_token_cannot_be_unary => { return Some((Token::UnaryPlus, start_pos)) } - ('+', _) => return Some((Token::Plus, start_pos)), + ('+', ..) => return Some((Token::Plus, start_pos)), ('-', '0'..='9') if !state.next_token_cannot_be_unary => negated = Some(start_pos), ('-', '0'..='9') => return Some((Token::Minus, start_pos)), @@ -1716,10 +1716,10 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::Reserved("--".into()), start_pos)); } - ('-', _) if !state.next_token_cannot_be_unary => { + ('-', ..) if !state.next_token_cannot_be_unary => { return Some((Token::UnaryMinus, start_pos)) } - ('-', _) => return Some((Token::Minus, start_pos)), + ('-', ..) => return Some((Token::Minus, start_pos)), ('*', ')') => { eat_next(stream, pos); @@ -1742,7 +1742,7 @@ fn get_next_token_inner( start_pos, )); } - ('*', _) => return Some((Token::Multiply, start_pos)), + ('*', ..) => return Some((Token::Multiply, start_pos)), // Comments ('/', '/') => { @@ -1819,10 +1819,10 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::DivideAssign, start_pos)); } - ('/', _) => return Some((Token::Divide, start_pos)), + ('/', ..) => return Some((Token::Divide, start_pos)), - (';', _) => return Some((Token::SemiColon, start_pos)), - (',', _) => return Some((Token::Comma, start_pos)), + (';', ..) => return Some((Token::SemiColon, start_pos)), + (',', ..) => return Some((Token::Comma, start_pos)), ('.', '.') => { eat_next(stream, pos); @@ -1841,7 +1841,7 @@ fn get_next_token_inner( start_pos, )); } - ('.', _) => return Some((Token::Period, start_pos)), + ('.', ..) => return Some((Token::Period, start_pos)), ('=', '=') => { eat_next(stream, pos); @@ -1857,7 +1857,7 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::DoubleArrow, start_pos)); } - ('=', _) => return Some((Token::Equals, start_pos)), + ('=', ..) => return Some((Token::Equals, start_pos)), #[cfg(not(feature = "no_module"))] (':', ':') => { @@ -1878,7 +1878,7 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::Reserved(":;".into()), start_pos)); } - (':', _) => return Some((Token::Colon, start_pos)), + (':', ..) => return Some((Token::Colon, start_pos)), ('<', '=') => { eat_next(stream, pos); @@ -1901,7 +1901,7 @@ fn get_next_token_inner( start_pos, )); } - ('<', _) => return Some((Token::LessThan, start_pos)), + ('<', ..) => return Some((Token::LessThan, start_pos)), ('>', '=') => { eat_next(stream, pos); @@ -1920,7 +1920,7 @@ fn get_next_token_inner( start_pos, )); } - ('>', _) => return Some((Token::GreaterThan, start_pos)), + ('>', ..) => return Some((Token::GreaterThan, start_pos)), ('!', '=') => { eat_next(stream, pos); @@ -1932,7 +1932,7 @@ fn get_next_token_inner( return Some((Token::NotEqualsTo, start_pos)); } - ('!', _) => return Some((Token::Bang, start_pos)), + ('!', ..) => return Some((Token::Bang, start_pos)), ('|', '|') => { eat_next(stream, pos); @@ -1942,7 +1942,7 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::OrAssign, start_pos)); } - ('|', _) => return Some((Token::Pipe, start_pos)), + ('|', ..) => return Some((Token::Pipe, start_pos)), ('&', '&') => { eat_next(stream, pos); @@ -1952,29 +1952,29 @@ fn get_next_token_inner( eat_next(stream, pos); return Some((Token::AndAssign, start_pos)); } - ('&', _) => return Some((Token::Ampersand, start_pos)), + ('&', ..) => return Some((Token::Ampersand, start_pos)), ('^', '=') => { eat_next(stream, pos); return Some((Token::XOrAssign, start_pos)); } - ('^', _) => return Some((Token::XOr, start_pos)), + ('^', ..) => return Some((Token::XOr, start_pos)), - ('~', _) => return Some((Token::Reserved("~".into()), start_pos)), + ('~', ..) => return Some((Token::Reserved("~".into()), start_pos)), ('%', '=') => { eat_next(stream, pos); return Some((Token::ModuloAssign, start_pos)); } - ('%', _) => return Some((Token::Modulo, start_pos)), + ('%', ..) => return Some((Token::Modulo, start_pos)), - ('@', _) => return Some((Token::Reserved("@".into()), start_pos)), + ('@', ..) => return Some((Token::Reserved("@".into()), start_pos)), - ('$', _) => return Some((Token::Reserved("$".into()), start_pos)), + ('$', ..) => return Some((Token::Reserved("$".into()), start_pos)), - (ch, _) if ch.is_whitespace() => (), + (ch, ..) if ch.is_whitespace() => (), - (ch, _) => { + (ch, ..) => { return Some(( Token::LexError(LERR::UnexpectedInput(ch.to_string())), start_pos, @@ -2232,14 +2232,14 @@ impl<'a> Iterator for TokenIterator<'a> { "'#' is not a valid symbol. Should it be '#{'?".to_string(), )), // Reserved keyword/operator that is custom. - (_, true) => Token::Custom(s), + (.., true) => Token::Custom(s), // Reserved keyword that is not custom and disabled. (token, false) if self.engine.disabled_symbols.contains(token) => { let msg = format!("reserved {} '{}' is disabled", if is_valid_identifier(token.chars()) { "keyword"} else {"symbol"}, token); Token::LexError(LERR::ImproperSymbol(s.to_string(), msg)) }, // Reserved keyword/operator that is not custom. - (_, false) => Token::Reserved(s), + (.., false) => Token::Reserved(s), }, pos), // Custom keyword Some((Token::Identifier(s), pos)) if self.engine.custom_keywords.contains_key(&*s) => { diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index ac2b85aa..d0a4d56a 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -344,7 +344,7 @@ impl Dynamic { #[inline(always)] #[must_use] pub const fn is_variant(&self) -> bool { - matches!(self.0, Union::Variant(_, _, _)) + matches!(self.0, Union::Variant(..)) } /// Is the value held by this [`Dynamic`] shared? /// @@ -354,7 +354,7 @@ impl Dynamic { #[must_use] pub const fn is_shared(&self) -> bool { #[cfg(not(feature = "no_closure"))] - return matches!(self.0, Union::Shared(_, _, _)); + return matches!(self.0, Union::Shared(..)); #[cfg(feature = "no_closure")] return false; } @@ -380,34 +380,34 @@ impl Dynamic { #[must_use] pub fn type_id(&self) -> TypeId { match self.0 { - Union::Unit(_, _, _) => TypeId::of::<()>(), - Union::Bool(_, _, _) => TypeId::of::(), - Union::Str(_, _, _) => TypeId::of::(), - Union::Char(_, _, _) => TypeId::of::(), - Union::Int(_, _, _) => TypeId::of::(), + Union::Unit(..) => TypeId::of::<()>(), + Union::Bool(..) => TypeId::of::(), + Union::Str(..) => TypeId::of::(), + Union::Char(..) => TypeId::of::(), + Union::Int(..) => TypeId::of::(), #[cfg(not(feature = "no_float"))] - Union::Float(_, _, _) => TypeId::of::(), + Union::Float(..) => TypeId::of::(), #[cfg(feature = "decimal")] - Union::Decimal(_, _, _) => TypeId::of::(), + Union::Decimal(..) => TypeId::of::(), #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => TypeId::of::(), + Union::Array(..) => TypeId::of::(), #[cfg(not(feature = "no_index"))] - Union::Blob(_, _, _) => TypeId::of::(), + Union::Blob(..) => TypeId::of::(), #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => TypeId::of::(), - Union::FnPtr(_, _, _) => TypeId::of::(), + Union::Map(..) => TypeId::of::(), + Union::FnPtr(..) => TypeId::of::(), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => TypeId::of::(), + Union::TimeStamp(..) => TypeId::of::(), - Union::Variant(ref v, _, _) => (***v).type_id(), + Union::Variant(ref v, _, ..) => (***v).type_id(), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => (*cell.borrow()).type_id(), + Union::Shared(ref cell, _, ..) => (*cell.borrow()).type_id(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_id(), + Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_id(), } } /// Get the name of the type of the value held by this [`Dynamic`]. @@ -419,36 +419,36 @@ impl Dynamic { #[must_use] pub fn type_name(&self) -> &'static str { match self.0 { - Union::Unit(_, _, _) => "()", - Union::Bool(_, _, _) => "bool", - Union::Str(_, _, _) => "string", - Union::Char(_, _, _) => "char", - Union::Int(_, _, _) => type_name::(), + Union::Unit(..) => "()", + Union::Bool(..) => "bool", + Union::Str(..) => "string", + Union::Char(..) => "char", + Union::Int(..) => type_name::(), #[cfg(not(feature = "no_float"))] - Union::Float(_, _, _) => type_name::(), + Union::Float(..) => type_name::(), #[cfg(feature = "decimal")] - Union::Decimal(_, _, _) => "decimal", + Union::Decimal(..) => "decimal", #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => "array", + Union::Array(..) => "array", #[cfg(not(feature = "no_index"))] - Union::Blob(_, _, _) => "blob", + Union::Blob(..) => "blob", #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => "map", - Union::FnPtr(_, _, _) => "Fn", + Union::Map(..) => "map", + Union::FnPtr(..) => "Fn", #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => "timestamp", + Union::TimeStamp(..) => "timestamp", - Union::Variant(ref v, _, _) => (***v).type_name(), + Union::Variant(ref v, _, ..) => (***v).type_name(), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => cell + Union::Shared(ref cell, _, ..) => cell .try_borrow() .map(|v| (*v).type_name()) .unwrap_or(""), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).type_name(), + Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_name(), } } } @@ -463,32 +463,32 @@ impl Hash for Dynamic { mem::discriminant(&self.0).hash(state); match self.0 { - Union::Unit(_, _, _) => ().hash(state), - Union::Bool(ref b, _, _) => b.hash(state), - Union::Str(ref s, _, _) => s.hash(state), - Union::Char(ref c, _, _) => c.hash(state), - Union::Int(ref i, _, _) => i.hash(state), + Union::Unit(..) => ().hash(state), + Union::Bool(ref b, _, ..) => b.hash(state), + Union::Str(ref s, _, ..) => s.hash(state), + Union::Char(ref c, _, ..) => c.hash(state), + Union::Int(ref i, _, ..) => i.hash(state), #[cfg(not(feature = "no_float"))] - Union::Float(ref f, _, _) => f.hash(state), + Union::Float(ref f, _, ..) => f.hash(state), #[cfg(feature = "decimal")] - Union::Decimal(ref d, _, _) => d.hash(state), + Union::Decimal(ref d, _, ..) => d.hash(state), #[cfg(not(feature = "no_index"))] - Union::Array(ref a, _, _) => a.as_ref().hash(state), + Union::Array(ref a, _, ..) => a.as_ref().hash(state), #[cfg(not(feature = "no_index"))] - Union::Blob(ref a, _, _) => a.as_ref().hash(state), + Union::Blob(ref a, _, ..) => a.as_ref().hash(state), #[cfg(not(feature = "no_object"))] - Union::Map(ref m, _, _) => m.as_ref().hash(state), - Union::FnPtr(ref f, _, _) => f.hash(state), + Union::Map(ref m, _, ..) => m.as_ref().hash(state), + Union::FnPtr(ref f, _, ..) => f.hash(state), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => (*cell.borrow()).hash(state), + Union::Shared(ref cell, _, ..) => (*cell.borrow()).hash(state), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => (*cell.read().unwrap()).hash(state), + Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).hash(state), - Union::Variant(ref v, _, _) => { + Union::Variant(ref v, _, ..) => { let _v = v; #[cfg(not(feature = "only_i32"))] @@ -537,7 +537,7 @@ impl Hash for Dynamic { } #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => unimplemented!("{} cannot be hashed", self.type_name()), + Union::TimeStamp(..) => unimplemented!("{} cannot be hashed", self.type_name()), } } } @@ -545,26 +545,26 @@ impl Hash for Dynamic { impl fmt::Display for Dynamic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.0 { - Union::Unit(_, _, _) => write!(f, ""), - Union::Bool(ref v, _, _) => fmt::Display::fmt(v, f), - Union::Str(ref v, _, _) => fmt::Display::fmt(v, f), - Union::Char(ref v, _, _) => fmt::Display::fmt(v, f), - Union::Int(ref v, _, _) => fmt::Display::fmt(v, f), + Union::Unit(..) => write!(f, ""), + Union::Bool(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Str(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Char(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Int(ref v, _, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_float"))] - Union::Float(ref v, _, _) => fmt::Display::fmt(v, f), + Union::Float(ref v, _, ..) => fmt::Display::fmt(v, f), #[cfg(feature = "decimal")] - Union::Decimal(ref v, _, _) => fmt::Display::fmt(v, f), + Union::Decimal(ref v, _, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => fmt::Debug::fmt(self, f), + Union::Array(..) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_index"))] - Union::Blob(_, _, _) => fmt::Debug::fmt(self, f), + Union::Blob(..) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => fmt::Debug::fmt(self, f), - Union::FnPtr(ref v, _, _) => fmt::Display::fmt(v, f), + Union::Map(..) => fmt::Debug::fmt(self, f), + Union::FnPtr(ref v, _, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => f.write_str(""), + Union::TimeStamp(..) => f.write_str(""), - Union::Variant(ref v, _, _) => { + Union::Variant(ref v, _, ..) => { let _value_any = (***v).as_any(); let _type_id = _value_any.type_id(); @@ -621,7 +621,7 @@ impl fmt::Display for Dynamic { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { if let Ok(v) = cell.try_borrow() { fmt::Display::fmt(&*v, f) } else { @@ -630,7 +630,7 @@ impl fmt::Display for Dynamic { } #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => fmt::Display::fmt(&*cell.read().unwrap(), f), + Union::Shared(ref cell, _, ..) => fmt::Display::fmt(&*cell.read().unwrap(), f), } } } @@ -638,19 +638,19 @@ impl fmt::Display for Dynamic { impl fmt::Debug for Dynamic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.0 { - Union::Unit(ref v, _, _) => fmt::Debug::fmt(v, f), - Union::Bool(ref v, _, _) => fmt::Debug::fmt(v, f), - Union::Str(ref v, _, _) => fmt::Debug::fmt(v, f), - Union::Char(ref v, _, _) => fmt::Debug::fmt(v, f), - Union::Int(ref v, _, _) => fmt::Debug::fmt(v, f), + Union::Unit(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Bool(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Str(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Char(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Int(ref v, _, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_float"))] - Union::Float(ref v, _, _) => fmt::Debug::fmt(v, f), + Union::Float(ref v, _, ..) => fmt::Debug::fmt(v, f), #[cfg(feature = "decimal")] - Union::Decimal(ref v, _, _) => fmt::Debug::fmt(v, f), + Union::Decimal(ref v, _, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_index"))] - Union::Array(ref v, _, _) => fmt::Debug::fmt(v, f), + Union::Array(ref v, _, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_index"))] - Union::Blob(ref v, _, _) => { + Union::Blob(ref v, _, ..) => { f.write_str("[")?; v.iter().enumerate().try_for_each(|(i, v)| { if i > 0 && i % 8 == 0 { @@ -661,15 +661,15 @@ impl fmt::Debug for Dynamic { f.write_str("]") } #[cfg(not(feature = "no_object"))] - Union::Map(ref v, _, _) => { + Union::Map(ref v, _, ..) => { f.write_str("#")?; fmt::Debug::fmt(v, f) } - Union::FnPtr(ref v, _, _) => fmt::Debug::fmt(v, f), + Union::FnPtr(ref v, _, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, _) => write!(f, ""), + Union::TimeStamp(..) => write!(f, ""), - Union::Variant(ref v, _, _) => { + Union::Variant(ref v, _, ..) => { let _value_any = (***v).as_any(); let _type_id = _value_any.type_id(); @@ -726,7 +726,7 @@ impl fmt::Debug for Dynamic { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { if let Ok(v) = cell.try_borrow() { write!(f, "{:?} (shared)", *v) } else { @@ -735,7 +735,7 @@ impl fmt::Debug for Dynamic { } #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => fmt::Debug::fmt(&*cell.read().unwrap(), f), + Union::Shared(ref cell, _, ..) => fmt::Debug::fmt(&*cell.read().unwrap(), f), } } } @@ -750,33 +750,33 @@ impl Clone for Dynamic { /// The cloned copy is marked read-write even if the original is read-only. fn clone(&self) -> Self { match self.0 { - Union::Unit(v, tag, _) => Self(Union::Unit(v, tag, ReadWrite)), - Union::Bool(v, tag, _) => Self(Union::Bool(v, tag, ReadWrite)), - Union::Str(ref v, tag, _) => Self(Union::Str(v.clone(), tag, ReadWrite)), - Union::Char(v, tag, _) => Self(Union::Char(v, tag, ReadWrite)), - Union::Int(v, tag, _) => Self(Union::Int(v, tag, ReadWrite)), + Union::Unit(v, tag, ..) => Self(Union::Unit(v, tag, ReadWrite)), + Union::Bool(v, tag, ..) => Self(Union::Bool(v, tag, ReadWrite)), + Union::Str(ref v, tag, ..) => Self(Union::Str(v.clone(), tag, ReadWrite)), + Union::Char(v, tag, ..) => Self(Union::Char(v, tag, ReadWrite)), + Union::Int(v, tag, ..) => Self(Union::Int(v, tag, ReadWrite)), #[cfg(not(feature = "no_float"))] - Union::Float(v, tag, _) => Self(Union::Float(v, tag, ReadWrite)), + Union::Float(v, tag, ..) => Self(Union::Float(v, tag, ReadWrite)), #[cfg(feature = "decimal")] - Union::Decimal(ref v, tag, _) => Self(Union::Decimal(v.clone(), tag, ReadWrite)), + Union::Decimal(ref v, tag, ..) => Self(Union::Decimal(v.clone(), tag, ReadWrite)), #[cfg(not(feature = "no_index"))] - Union::Array(ref v, tag, _) => Self(Union::Array(v.clone(), tag, ReadWrite)), + Union::Array(ref v, tag, ..) => Self(Union::Array(v.clone(), tag, ReadWrite)), #[cfg(not(feature = "no_index"))] - Union::Blob(ref v, tag, _) => Self(Union::Blob(v.clone(), tag, ReadWrite)), + Union::Blob(ref v, tag, ..) => Self(Union::Blob(v.clone(), tag, ReadWrite)), #[cfg(not(feature = "no_object"))] - Union::Map(ref v, tag, _) => Self(Union::Map(v.clone(), tag, ReadWrite)), - Union::FnPtr(ref v, tag, _) => Self(Union::FnPtr(v.clone(), tag, ReadWrite)), + Union::Map(ref v, tag, ..) => Self(Union::Map(v.clone(), tag, ReadWrite)), + Union::FnPtr(ref v, tag, ..) => Self(Union::FnPtr(v.clone(), tag, ReadWrite)), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(ref v, tag, _) => Self(Union::TimeStamp(v.clone(), tag, ReadWrite)), + Union::TimeStamp(ref v, tag, ..) => Self(Union::TimeStamp(v.clone(), tag, ReadWrite)), - Union::Variant(ref v, tag, _) => Self(Union::Variant( + Union::Variant(ref v, tag, ..) => Self(Union::Variant( v.as_ref().as_ref().clone_object().into(), tag, ReadWrite, )), #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, tag, _) => Self(Union::Shared(cell.clone(), tag, ReadWrite)), + Union::Shared(ref cell, tag, ..) => Self(Union::Shared(cell.clone(), tag, ReadWrite)), } } } @@ -1010,43 +1010,43 @@ impl Dynamic { #[must_use] pub(crate) const fn access_mode(&self) -> AccessMode { match self.0 { - Union::Unit(_, _, access) - | Union::Bool(_, _, access) - | Union::Str(_, _, access) - | Union::Char(_, _, access) - | Union::Int(_, _, access) - | Union::FnPtr(_, _, access) - | Union::Variant(_, _, access) => access, + Union::Unit(.., _, access) + | Union::Bool(.., _, access) + | Union::Str(.., _, access) + | Union::Char(.., _, access) + | Union::Int(.., _, access) + | Union::FnPtr(.., _, access) + | Union::Variant(.., _, access) => access, #[cfg(not(feature = "no_float"))] - Union::Float(_, _, access) => access, + Union::Float(.., _, access) => access, #[cfg(feature = "decimal")] - Union::Decimal(_, _, access) => access, + Union::Decimal(.., _, access) => access, #[cfg(not(feature = "no_index"))] - Union::Array(_, _, access) | Union::Blob(_, _, access) => access, + Union::Array(.., _, access) | Union::Blob(.., _, access) => access, #[cfg(not(feature = "no_object"))] - Union::Map(_, _, access) => access, + Union::Map(.., _, access) => access, #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, access) => access, + Union::TimeStamp(.., _, access) => access, #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, access) => access, + Union::Shared(.., _, access) => access, } } /// Set the [`AccessMode`] for this [`Dynamic`]. pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self { match self.0 { - Union::Unit(_, _, ref mut access) - | Union::Bool(_, _, ref mut access) - | Union::Str(_, _, ref mut access) - | Union::Char(_, _, ref mut access) - | Union::Int(_, _, ref mut access) - | Union::FnPtr(_, _, ref mut access) - | Union::Variant(_, _, ref mut access) => *access = typ, + Union::Unit(.., _, ref mut access) + | Union::Bool(.., _, ref mut access) + | Union::Str(.., _, ref mut access) + | Union::Char(.., _, ref mut access) + | Union::Int(.., _, ref mut access) + | Union::FnPtr(.., _, ref mut access) + | Union::Variant(.., _, ref mut access) => *access = typ, #[cfg(not(feature = "no_float"))] - Union::Float(_, _, ref mut access) => *access = typ, + Union::Float(.., _, ref mut access) => *access = typ, #[cfg(feature = "decimal")] - Union::Decimal(_, _, ref mut access) => *access = typ, + Union::Decimal(.., _, ref mut access) => *access = typ, #[cfg(not(feature = "no_index"))] Union::Array(ref mut a, _, ref mut access) => { *access = typ; @@ -1055,7 +1055,7 @@ impl Dynamic { } } #[cfg(not(feature = "no_index"))] - Union::Blob(_, _, ref mut access) => *access = typ, + Union::Blob(.., _, ref mut access) => *access = typ, #[cfg(not(feature = "no_object"))] Union::Map(ref mut m, _, ref mut access) => { *access = typ; @@ -1064,9 +1064,9 @@ impl Dynamic { } } #[cfg(not(feature = "no_std"))] - Union::TimeStamp(_, _, ref mut access) => *access = typ, + Union::TimeStamp(.., _, ref mut access) => *access = typ, #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, ref mut access) => *access = typ, + Union::Shared(.., _, ref mut access) => *access = typ, } self } @@ -1081,17 +1081,17 @@ impl Dynamic { pub fn is_read_only(&self) -> bool { #[cfg(not(feature = "no_closure"))] match self.0 { - Union::Shared(_, _, ReadOnly) => return true, + Union::Shared(.., _, ReadOnly) => return true, #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { return match cell.borrow().access_mode() { ReadWrite => false, ReadOnly => true, } } #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { return match cell.read().unwrap().access_mode() { ReadWrite => false, ReadOnly => true, @@ -1110,26 +1110,26 @@ impl Dynamic { #[must_use] pub(crate) fn is_hashable(&self) -> bool { match self.0 { - Union::Unit(_, _, _) - | Union::Bool(_, _, _) - | Union::Str(_, _, _) - | Union::Char(_, _, _) - | Union::Int(_, _, _) => true, + Union::Unit(..) + | Union::Bool(..) + | Union::Str(..) + | Union::Char(..) + | Union::Int(..) => true, #[cfg(not(feature = "no_float"))] - Union::Float(_, _, _) => true, + Union::Float(..) => true, #[cfg(not(feature = "no_index"))] - Union::Array(_, _, _) => true, + Union::Array(..) => true, #[cfg(not(feature = "no_object"))] - Union::Map(_, _, _) => true, + Union::Map(..) => true, #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => cell.borrow().is_hashable(), + Union::Shared(ref cell, _, ..) => cell.borrow().is_hashable(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => cell.read().unwrap().is_hashable(), + Union::Shared(ref cell, _, ..) => cell.read().unwrap().is_hashable(), _ => false, } @@ -1229,7 +1229,7 @@ impl Dynamic { let _access = self.access_mode(); match self.0 { - Union::Shared(_, _, _) => self, + Union::Shared(..) => self, _ => Self(Union::Shared( crate::Locked::new(self).into(), DEFAULT_TAG_VALUE, @@ -1266,7 +1266,7 @@ impl Dynamic { // Coded this way in order to maximally leverage potentials for dead-code removal. #[cfg(not(feature = "no_closure"))] - if let Union::Shared(_, _, _) = self.0 { + if let Union::Shared(..) = self.0 { return self.flatten().try_cast::(); } @@ -1294,10 +1294,12 @@ impl Dynamic { Union::FnPtr(v, ..) => reify!(v, |v: Box| Some(*v), || None), #[cfg(not(feature = "no_std"))] Union::TimeStamp(v, ..) => reify!(v, |v: Box| Some(*v), || None), - Union::Unit(_, ..) => reify!((), |v: T| Some(v), || None), - Union::Variant(v, _, _) => (*v).as_boxed_any().downcast().ok().map(|x| *x), + Union::Unit(..) => reify!((), |v: T| Some(v), || None), + Union::Variant(v, _, ..) => (*v).as_boxed_any().downcast().ok().map(|x| *x), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => unreachable!("Union::Shared case should be already handled"), + Union::Shared(..) => { + unreachable!("Union::Shared case should be already handled") + } } } /// Convert the [`Dynamic`] value into a specific type. @@ -1382,10 +1384,10 @@ impl Dynamic { match self.0 { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, _) => cell.borrow().clone(), + Union::Shared(ref cell, _, ..) => cell.borrow().clone(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, _) => cell.read().unwrap().clone(), + Union::Shared(ref cell, _, ..) => cell.read().unwrap().clone(), _ => self.clone(), } } @@ -1400,7 +1402,7 @@ impl Dynamic { pub fn flatten(self) -> Self { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, _) => crate::func::native::shared_try_take(cell).map_or_else( + Union::Shared(cell, _, ..) => crate::func::native::shared_try_take(cell).map_or_else( #[cfg(not(feature = "sync"))] |cell| cell.borrow().clone(), #[cfg(feature = "sync")] @@ -1423,7 +1425,7 @@ impl Dynamic { pub(crate) fn flatten_in_place(&mut self) -> &mut Self { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref mut cell, _, _) => { + Union::Shared(ref mut cell, _, ..) => { let cell = mem::take(cell); *self = crate::func::native::shared_try_take(cell).map_or_else( #[cfg(not(feature = "sync"))] @@ -1455,7 +1457,7 @@ impl Dynamic { pub fn is_locked(&self) -> bool { #[cfg(not(feature = "no_closure"))] match self.0 { - Union::Shared(ref _cell, _, _) => { + Union::Shared(ref _cell, _, ..) => { #[cfg(not(feature = "sync"))] return _cell.try_borrow().is_err(); #[cfg(feature = "sync")] @@ -1480,7 +1482,7 @@ impl Dynamic { pub fn read_lock(&self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] @@ -1515,7 +1517,7 @@ impl Dynamic { pub fn write_lock(&mut self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, _, _) => { + Union::Shared(ref cell, _, ..) => { let guard = crate::func::native::locked_write(cell); if (*guard).type_id() != TypeId::of::() @@ -1544,79 +1546,79 @@ impl Dynamic { if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Int(ref v, _, _) => v.as_any().downcast_ref::(), + Union::Int(ref v, _, ..) => v.as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_float"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Float(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::Float(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(feature = "decimal")] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Decimal(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::Decimal(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Bool(ref v, _, _) => v.as_any().downcast_ref::(), + Union::Bool(ref v, _, ..) => v.as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(ref v, _, _) => v.as_any().downcast_ref::(), + Union::Str(ref v, _, ..) => v.as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Char(ref v, _, _) => v.as_any().downcast_ref::(), + Union::Char(ref v, _, ..) => v.as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Array(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::Array(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Blob(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::Blob(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_object"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Map(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::Map(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::FnPtr(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::FnPtr(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_std"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::TimeStamp(ref v, _, _) => v.as_ref().as_any().downcast_ref::(), + Union::TimeStamp(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::<()>() { return match self.0 { - Union::Unit(ref v, _, _) => v.as_any().downcast_ref::(), + Union::Unit(ref v, _, ..) => v.as_any().downcast_ref::(), _ => None, }; } @@ -1625,9 +1627,9 @@ impl Dynamic { } match self.0 { - Union::Variant(ref v, _, _) => (***v).as_any().downcast_ref::(), + Union::Variant(ref v, _, ..) => (***v).as_any().downcast_ref::(), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => None, + Union::Shared(..) => None, _ => None, } } @@ -1642,79 +1644,79 @@ impl Dynamic { if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Int(ref mut v, _, _) => v.as_any_mut().downcast_mut::(), + Union::Int(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_float"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Float(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Float(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(feature = "decimal")] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Decimal(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Decimal(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Bool(ref mut v, _, _) => v.as_any_mut().downcast_mut::(), + Union::Bool(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(ref mut v, _, _) => v.as_any_mut().downcast_mut::(), + Union::Str(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Char(ref mut v, _, _) => v.as_any_mut().downcast_mut::(), + Union::Char(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Array(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Array(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Blob(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Blob(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_object"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Map(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Map(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::FnPtr(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::FnPtr(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_std"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::TimeStamp(ref mut v, _, _) => v.as_mut().as_any_mut().downcast_mut::(), + Union::TimeStamp(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::<()>() { return match self.0 { - Union::Unit(ref mut v, _, _) => v.as_any_mut().downcast_mut::(), + Union::Unit(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } @@ -1723,9 +1725,9 @@ impl Dynamic { } match self.0 { - Union::Variant(ref mut v, _, _) => (***v).as_any_mut().downcast_mut::(), + Union::Variant(ref mut v, _, ..) => (***v).as_any_mut().downcast_mut::(), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => None, + Union::Shared(..) => None, _ => None, } } @@ -1734,9 +1736,9 @@ impl Dynamic { #[inline] pub fn as_unit(&self) -> Result<(), &'static str> { match self.0 { - Union::Unit(v, _, _) => Ok(v), + Union::Unit(v, _, ..) => Ok(v), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1745,9 +1747,9 @@ impl Dynamic { #[inline] pub fn as_int(&self) -> Result { match self.0 { - Union::Int(n, _, _) => Ok(n), + Union::Int(n, _, ..) => Ok(n), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1759,9 +1761,9 @@ impl Dynamic { #[inline] pub fn as_float(&self) -> Result { match self.0 { - Union::Float(n, _, _) => Ok(*n), + Union::Float(n, _, ..) => Ok(*n), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1773,9 +1775,9 @@ impl Dynamic { #[inline] pub fn as_decimal(&self) -> Result { match self.0 { - Union::Decimal(ref n, _, _) => Ok(**n), + Union::Decimal(ref n, _, ..) => Ok(**n), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1784,9 +1786,9 @@ impl Dynamic { #[inline] pub fn as_bool(&self) -> Result { match self.0 { - Union::Bool(b, _, _) => Ok(b), + Union::Bool(b, _, ..) => Ok(b), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1795,9 +1797,9 @@ impl Dynamic { #[inline] pub fn as_char(&self) -> Result { match self.0 { - Union::Char(n, _, _) => Ok(n), + Union::Char(n, _, ..) => Ok(n), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), + Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), } } @@ -1810,9 +1812,9 @@ impl Dynamic { #[inline] pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> { match self.0 { - Union::Str(ref s, _, _) => Ok(s), + Union::Str(ref s, _, ..) => Ok(s), #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => panic!("as_str_ref() cannot be called on shared values"), + Union::Shared(..) => panic!("as_str_ref() cannot be called on shared values"), _ => Err(self.type_name()), } } @@ -1829,16 +1831,16 @@ impl Dynamic { #[inline] pub fn into_immutable_string(self) -> Result { match self.0 { - Union::Str(s, _, _) => Ok(s), + Union::Str(s, _, ..) => Ok(s), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, _) => { + Union::Shared(cell, _, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Str(ref s, _, _) => Ok(s.clone()), + Union::Str(ref s, _, ..) => Ok(s.clone()), _ => Err((*value).type_name()), } } @@ -1851,16 +1853,16 @@ impl Dynamic { #[inline(always)] pub fn into_array(self) -> Result { match self.0 { - Union::Array(a, _, _) => Ok(*a), + Union::Array(a, _, ..) => Ok(*a), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, _) => { + Union::Shared(cell, _, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Array(ref a, _, _) => Ok(a.as_ref().clone()), + Union::Array(ref a, _, ..) => Ok(a.as_ref().clone()), _ => Err((*value).type_name()), } } @@ -1873,7 +1875,7 @@ impl Dynamic { #[inline(always)] pub fn into_typed_array(self) -> Result, &'static str> { match self.0 { - Union::Array(a, _, _) => a + Union::Array(a, _, ..) => a .into_iter() .map(|v| { #[cfg(not(feature = "no_closure"))] @@ -1889,18 +1891,16 @@ impl Dynamic { v.try_cast::().ok_or_else(|| typ) }) .collect(), - Union::Blob(_, _, _) if TypeId::of::() == TypeId::of::() => { - Ok(self.cast::>()) - } + Union::Blob(..) if TypeId::of::() == TypeId::of::() => Ok(self.cast::>()), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, _) => { + Union::Shared(cell, _, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Array(ref a, _, _) => { + Union::Array(ref a, _, ..) => { a.iter() .map(|v| { #[cfg(not(feature = "no_closure"))] @@ -1917,7 +1917,7 @@ impl Dynamic { }) .collect() } - Union::Blob(_, _, _) if TypeId::of::() == TypeId::of::() => { + Union::Blob(..) if TypeId::of::() == TypeId::of::() => { Ok((*value).clone().cast::>()) } _ => Err((*value).type_name()), @@ -1932,16 +1932,16 @@ impl Dynamic { #[inline(always)] pub fn into_blob(self) -> Result { match self.0 { - Union::Blob(a, _, _) => Ok(*a), + Union::Blob(a, _, ..) => Ok(*a), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, _) => { + Union::Shared(cell, _, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Blob(ref a, _, _) => Ok(a.as_ref().clone()), + Union::Blob(ref a, _, ..) => Ok(a.as_ref().clone()), _ => Err((*value).type_name()), } } diff --git a/src/types/error.rs b/src/types/error.rs index 60fc5d41..93044334 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -120,77 +120,77 @@ impl fmt::Display for EvalAltResult { s => write!(f, "{}: {}", s, err), }?, - Self::ErrorParsing(p, _) => write!(f, "Syntax error: {}", p)?, + Self::ErrorParsing(p, ..) => write!(f, "Syntax error: {}", p)?, #[cfg(not(feature = "no_function"))] - Self::ErrorInFunctionCall(s, src, err, _) if crate::parser::is_anonymous_fn(s) => { + Self::ErrorInFunctionCall(s, src, err, ..) if crate::parser::is_anonymous_fn(s) => { write!(f, "{} in call to closure", err)?; if !src.is_empty() { write!(f, " @ '{}'", src)?; } } - Self::ErrorInFunctionCall(s, src, err, _) => { + Self::ErrorInFunctionCall(s, src, err, ..) => { write!(f, "{} in call to function {}", err, s)?; if !src.is_empty() { write!(f, " @ '{}'", src)?; } } - Self::ErrorInModule(s, err, _) if s.is_empty() => { + Self::ErrorInModule(s, err, ..) if s.is_empty() => { write!(f, "Error in module: {}", err)? } - Self::ErrorInModule(s, err, _) => write!(f, "Error in module {}: {}", s, err)?, + Self::ErrorInModule(s, err, ..) => write!(f, "Error in module {}: {}", s, err)?, - Self::ErrorVariableExists(s, _) => write!(f, "Variable is already defined: {}", s)?, - Self::ErrorVariableNotFound(s, _) => write!(f, "Variable not found: {}", s)?, - Self::ErrorFunctionNotFound(s, _) => write!(f, "Function not found: {}", s)?, - Self::ErrorModuleNotFound(s, _) => write!(f, "Module not found: {}", s)?, - Self::ErrorDataRace(s, _) => { + Self::ErrorVariableExists(s, ..) => write!(f, "Variable is already defined: {}", s)?, + Self::ErrorVariableNotFound(s, ..) => write!(f, "Variable not found: {}", s)?, + Self::ErrorFunctionNotFound(s, ..) => write!(f, "Function not found: {}", s)?, + Self::ErrorModuleNotFound(s, ..) => write!(f, "Module not found: {}", s)?, + Self::ErrorDataRace(s, ..) => { write!(f, "Data race detected when accessing variable: {}", s)? } - Self::ErrorDotExpr(s, _) => match s.as_str() { + Self::ErrorDotExpr(s, ..) => match s.as_str() { "" => f.write_str("Malformed dot expression"), s => f.write_str(s), }?, - Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered: {}", s)?, + Self::ErrorIndexingType(s, ..) => write!(f, "Indexer not registered: {}", s)?, Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?, Self::ErrorFor(_) => f.write_str("For loop expects a type that is iterable")?, Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?, Self::ErrorTooManyModules(_) => f.write_str("Too many modules imported")?, Self::ErrorStackOverflow(_) => f.write_str("Stack overflow")?, - Self::ErrorTerminated(_, _) => f.write_str("Script terminated")?, + Self::ErrorTerminated(..) => f.write_str("Script terminated")?, - Self::ErrorRuntime(d, _) if d.is::<()>() => f.write_str("Runtime error")?, - Self::ErrorRuntime(d, _) + Self::ErrorRuntime(d, ..) if d.is::<()>() => f.write_str("Runtime error")?, + Self::ErrorRuntime(d, ..) if d.read_lock::() .map_or(false, |v| v.is_empty()) => { write!(f, "Runtime error")? } - Self::ErrorRuntime(d, _) => write!(f, "Runtime error: {}", d)?, + Self::ErrorRuntime(d, ..) => write!(f, "Runtime error: {}", d)?, - Self::ErrorAssignmentToConstant(s, _) => write!(f, "Cannot modify constant: {}", s)?, - Self::ErrorMismatchOutputType(s, r, _) => match (r.as_str(), s.as_str()) { + Self::ErrorAssignmentToConstant(s, ..) => write!(f, "Cannot modify constant: {}", s)?, + Self::ErrorMismatchOutputType(s, r, ..) => match (r.as_str(), s.as_str()) { ("", s) => write!(f, "Output type is incorrect, expecting {}", s), (r, "") => write!(f, "Output type is incorrect: {}", r), (r, s) => write!(f, "Output type is incorrect: {} (expecting {})", r, s), }?, - Self::ErrorMismatchDataType(s, r, _) => match (r.as_str(), s.as_str()) { + Self::ErrorMismatchDataType(s, r, ..) => match (r.as_str(), s.as_str()) { ("", s) => write!(f, "Data type is incorrect, expecting {}", s), (r, "") => write!(f, "Data type is incorrect: {}", r), (r, s) => write!(f, "Data type is incorrect: {} (expecting {})", r, s), }?, - Self::ErrorArithmetic(s, _) => match s.as_str() { + Self::ErrorArithmetic(s, ..) => match s.as_str() { "" => f.write_str("Arithmetic error"), s => f.write_str(s), }?, - Self::LoopBreak(true, _) => f.write_str("'break' not inside a loop")?, - Self::LoopBreak(false, _) => f.write_str("'continue' not inside a loop")?, + Self::LoopBreak(true, ..) => f.write_str("'break' not inside a loop")?, + Self::LoopBreak(false, ..) => f.write_str("'continue' not inside a loop")?, - Self::Return(_, _) => f.write_str("NOT AN ERROR - function returns value")?, + Self::Return(..) => f.write_str("NOT AN ERROR - function returns value")?, - Self::ErrorArrayBounds(max, index, _) => match max { + Self::ErrorArrayBounds(max, index, ..) => match max { 0 => write!(f, "Array index {} out of bounds: array is empty", index), 1 => write!( f, @@ -203,7 +203,7 @@ impl fmt::Display for EvalAltResult { index, max ), }?, - Self::ErrorStringBounds(max, index, _) => match max { + Self::ErrorStringBounds(max, index, ..) => match max { 0 => write!(f, "String index {} out of bounds: string is empty", index), 1 => write!( f, @@ -216,14 +216,14 @@ impl fmt::Display for EvalAltResult { index, max ), }?, - Self::ErrorBitFieldBounds(max, index, _) => write!( + Self::ErrorBitFieldBounds(max, index, ..) => write!( f, "Bit-field index {} out of bounds: only {} bits in the bit-field", index, max )?, - Self::ErrorDataTooLarge(typ, _) => write!(f, "{} exceeds maximum limit", typ)?, + Self::ErrorDataTooLarge(typ, ..) => write!(f, "{} exceeds maximum limit", typ)?, - Self::ErrorCustomSyntax(s, tokens, _) => write!(f, "{}: {}", s, tokens.join(" "))?, + Self::ErrorCustomSyntax(s, tokens, ..) => write!(f, "{}: {}", s, tokens.join(" "))?, } // Do not write any position if None @@ -256,7 +256,7 @@ impl EvalAltResult { #[must_use] pub const fn is_pseudo_error(&self) -> bool { match self { - Self::LoopBreak(_, _) | Self::Return(_, _) => true, + Self::LoopBreak(..) | Self::Return(..) => true, _ => false, } } @@ -264,58 +264,58 @@ impl EvalAltResult { #[must_use] pub const fn is_catchable(&self) -> bool { match self { - Self::ErrorSystem(_, _) => false, - Self::ErrorParsing(_, _) => false, + Self::ErrorSystem(..) => false, + Self::ErrorParsing(..) => false, - Self::ErrorFunctionNotFound(_, _) - | Self::ErrorInFunctionCall(_, _, _, _) - | Self::ErrorInModule(_, _, _) + Self::ErrorFunctionNotFound(..) + | Self::ErrorInFunctionCall(..) + | Self::ErrorInModule(..) | Self::ErrorUnboundThis(_) - | Self::ErrorMismatchDataType(_, _, _) - | Self::ErrorArrayBounds(_, _, _) - | Self::ErrorStringBounds(_, _, _) - | Self::ErrorBitFieldBounds(_, _, _) - | Self::ErrorIndexingType(_, _) + | Self::ErrorMismatchDataType(..) + | Self::ErrorArrayBounds(..) + | Self::ErrorStringBounds(..) + | Self::ErrorBitFieldBounds(..) + | Self::ErrorIndexingType(..) | Self::ErrorFor(_) - | Self::ErrorVariableExists(_, _) - | Self::ErrorVariableNotFound(_, _) - | Self::ErrorModuleNotFound(_, _) - | Self::ErrorDataRace(_, _) - | Self::ErrorAssignmentToConstant(_, _) - | Self::ErrorMismatchOutputType(_, _, _) - | Self::ErrorDotExpr(_, _) - | Self::ErrorArithmetic(_, _) - | Self::ErrorRuntime(_, _) => true, + | Self::ErrorVariableExists(..) + | Self::ErrorVariableNotFound(..) + | Self::ErrorModuleNotFound(..) + | Self::ErrorDataRace(..) + | Self::ErrorAssignmentToConstant(..) + | Self::ErrorMismatchOutputType(..) + | Self::ErrorDotExpr(..) + | Self::ErrorArithmetic(..) + | Self::ErrorRuntime(..) => true, // Custom syntax raises errors only when they are compiled by one // [`Engine`][crate::Engine] and run by another, causing a mismatch. // // Therefore, this error should not be catchable. - Self::ErrorCustomSyntax(_, _, _) => false, + Self::ErrorCustomSyntax(..) => false, Self::ErrorTooManyOperations(_) | Self::ErrorTooManyModules(_) | Self::ErrorStackOverflow(_) - | Self::ErrorDataTooLarge(_, _) - | Self::ErrorTerminated(_, _) => false, + | Self::ErrorDataTooLarge(..) + | Self::ErrorTerminated(..) => false, - Self::LoopBreak(_, _) | Self::Return(_, _) => false, + Self::LoopBreak(..) | Self::Return(..) => false, } } /// Is this error a system exception? #[must_use] pub const fn is_system_exception(&self) -> bool { match self { - Self::ErrorSystem(_, _) => true, - Self::ErrorParsing(_, _) => true, + Self::ErrorSystem(..) => true, + Self::ErrorParsing(..) => true, - Self::ErrorCustomSyntax(_, _, _) + Self::ErrorCustomSyntax(..) | Self::ErrorTooManyOperations(_) | Self::ErrorTooManyModules(_) | Self::ErrorStackOverflow(_) - | Self::ErrorDataTooLarge(_, _) => true, + | Self::ErrorDataTooLarge(..) => true, - Self::ErrorTerminated(_, _) => true, + Self::ErrorTerminated(..) => true, _ => false, } @@ -333,58 +333,58 @@ impl EvalAltResult { ); match self { - Self::LoopBreak(_, _) | Self::Return(_, _) => (), + Self::LoopBreak(..) | Self::Return(..) => (), - Self::ErrorSystem(_, _) - | Self::ErrorParsing(_, _) + Self::ErrorSystem(..) + | Self::ErrorParsing(..) | Self::ErrorUnboundThis(_) | Self::ErrorFor(_) - | Self::ErrorArithmetic(_, _) + | Self::ErrorArithmetic(..) | Self::ErrorTooManyOperations(_) | Self::ErrorTooManyModules(_) | Self::ErrorStackOverflow(_) - | Self::ErrorRuntime(_, _) => (), + | Self::ErrorRuntime(..) => (), - Self::ErrorFunctionNotFound(f, _) => { + Self::ErrorFunctionNotFound(f, ..) => { map.insert("function".into(), f.into()); } - Self::ErrorInFunctionCall(f, s, _, _) => { + Self::ErrorInFunctionCall(f, s, ..) => { map.insert("function".into(), f.into()); map.insert("source".into(), s.into()); } - Self::ErrorInModule(m, _, _) => { + Self::ErrorInModule(m, ..) => { map.insert("module".into(), m.into()); } - Self::ErrorMismatchDataType(r, a, _) | Self::ErrorMismatchOutputType(r, a, _) => { + Self::ErrorMismatchDataType(r, a, ..) | Self::ErrorMismatchOutputType(r, a, ..) => { map.insert("requested".into(), r.into()); map.insert("actual".into(), a.into()); } - Self::ErrorArrayBounds(n, i, _) - | Self::ErrorStringBounds(n, i, _) - | Self::ErrorBitFieldBounds(n, i, _) => { + Self::ErrorArrayBounds(n, i, ..) + | Self::ErrorStringBounds(n, i, ..) + | Self::ErrorBitFieldBounds(n, i, ..) => { map.insert("length".into(), (*n as INT).into()); map.insert("index".into(), (*i as INT).into()); } - Self::ErrorIndexingType(t, _) => { + Self::ErrorIndexingType(t, ..) => { map.insert("type".into(), t.into()); } - Self::ErrorVariableExists(v, _) - | Self::ErrorVariableNotFound(v, _) - | Self::ErrorDataRace(v, _) - | Self::ErrorAssignmentToConstant(v, _) => { + Self::ErrorVariableExists(v, ..) + | Self::ErrorVariableNotFound(v, ..) + | Self::ErrorDataRace(v, ..) + | Self::ErrorAssignmentToConstant(v, ..) => { map.insert("variable".into(), v.into()); } - Self::ErrorModuleNotFound(m, _) => { + Self::ErrorModuleNotFound(m, ..) => { map.insert("module".into(), m.into()); } - Self::ErrorDotExpr(p, _) => { + Self::ErrorDotExpr(p, ..) => { map.insert("property".into(), p.into()); } - Self::ErrorDataTooLarge(t, _) => { + Self::ErrorDataTooLarge(t, ..) => { map.insert("type".into(), t.into()); } - Self::ErrorTerminated(t, _) => { + Self::ErrorTerminated(t, ..) => { map.insert("token".into(), t.clone()); } Self::ErrorCustomSyntax(_, tokens, _) => { @@ -407,36 +407,36 @@ impl EvalAltResult { #[must_use] pub const fn position(&self) -> Position { match self { - Self::ErrorSystem(_, _) => Position::NONE, + Self::ErrorSystem(..) => Position::NONE, - Self::ErrorParsing(_, pos) - | Self::ErrorFunctionNotFound(_, pos) - | Self::ErrorInFunctionCall(_, _, _, pos) - | Self::ErrorInModule(_, _, pos) + Self::ErrorParsing(.., pos) + | Self::ErrorFunctionNotFound(.., pos) + | Self::ErrorInFunctionCall(.., pos) + | Self::ErrorInModule(.., pos) | Self::ErrorUnboundThis(pos) - | Self::ErrorMismatchDataType(_, _, pos) - | Self::ErrorArrayBounds(_, _, pos) - | Self::ErrorStringBounds(_, _, pos) - | Self::ErrorBitFieldBounds(_, _, pos) - | Self::ErrorIndexingType(_, pos) + | Self::ErrorMismatchDataType(.., pos) + | Self::ErrorArrayBounds(.., pos) + | Self::ErrorStringBounds(.., pos) + | Self::ErrorBitFieldBounds(.., pos) + | Self::ErrorIndexingType(.., pos) | Self::ErrorFor(pos) - | Self::ErrorVariableExists(_, pos) - | Self::ErrorVariableNotFound(_, pos) - | Self::ErrorModuleNotFound(_, pos) - | Self::ErrorDataRace(_, pos) - | Self::ErrorAssignmentToConstant(_, pos) - | Self::ErrorMismatchOutputType(_, _, pos) - | Self::ErrorDotExpr(_, pos) - | Self::ErrorArithmetic(_, pos) + | Self::ErrorVariableExists(.., pos) + | Self::ErrorVariableNotFound(.., pos) + | Self::ErrorModuleNotFound(.., pos) + | Self::ErrorDataRace(.., pos) + | Self::ErrorAssignmentToConstant(.., pos) + | Self::ErrorMismatchOutputType(.., pos) + | Self::ErrorDotExpr(.., pos) + | Self::ErrorArithmetic(.., pos) | Self::ErrorTooManyOperations(pos) | Self::ErrorTooManyModules(pos) | Self::ErrorStackOverflow(pos) - | Self::ErrorDataTooLarge(_, pos) - | Self::ErrorTerminated(_, pos) - | Self::ErrorCustomSyntax(_, _, pos) - | Self::ErrorRuntime(_, pos) - | Self::LoopBreak(_, pos) - | Self::Return(_, pos) => *pos, + | Self::ErrorDataTooLarge(.., pos) + | Self::ErrorTerminated(.., pos) + | Self::ErrorCustomSyntax(.., pos) + | Self::ErrorRuntime(.., pos) + | Self::LoopBreak(.., pos) + | Self::Return(.., pos) => *pos, } } /// Remove the [position][Position] information from this error. @@ -456,36 +456,36 @@ impl EvalAltResult { /// Override the [position][Position] of this error. pub fn set_position(&mut self, new_position: Position) -> &mut Self { match self { - Self::ErrorSystem(_, _) => (), + Self::ErrorSystem(..) => (), - Self::ErrorParsing(_, pos) - | Self::ErrorFunctionNotFound(_, pos) - | Self::ErrorInFunctionCall(_, _, _, pos) - | Self::ErrorInModule(_, _, pos) + Self::ErrorParsing(.., pos) + | Self::ErrorFunctionNotFound(.., pos) + | Self::ErrorInFunctionCall(.., pos) + | Self::ErrorInModule(.., pos) | Self::ErrorUnboundThis(pos) - | Self::ErrorMismatchDataType(_, _, pos) - | Self::ErrorArrayBounds(_, _, pos) - | Self::ErrorStringBounds(_, _, pos) - | Self::ErrorBitFieldBounds(_, _, pos) - | Self::ErrorIndexingType(_, pos) + | Self::ErrorMismatchDataType(.., pos) + | Self::ErrorArrayBounds(.., pos) + | Self::ErrorStringBounds(.., pos) + | Self::ErrorBitFieldBounds(.., pos) + | Self::ErrorIndexingType(.., pos) | Self::ErrorFor(pos) - | Self::ErrorVariableExists(_, pos) - | Self::ErrorVariableNotFound(_, pos) - | Self::ErrorModuleNotFound(_, pos) - | Self::ErrorDataRace(_, pos) - | Self::ErrorAssignmentToConstant(_, pos) - | Self::ErrorMismatchOutputType(_, _, pos) - | Self::ErrorDotExpr(_, pos) - | Self::ErrorArithmetic(_, pos) + | Self::ErrorVariableExists(.., pos) + | Self::ErrorVariableNotFound(.., pos) + | Self::ErrorModuleNotFound(.., pos) + | Self::ErrorDataRace(.., pos) + | Self::ErrorAssignmentToConstant(.., pos) + | Self::ErrorMismatchOutputType(.., pos) + | Self::ErrorDotExpr(.., pos) + | Self::ErrorArithmetic(.., pos) | Self::ErrorTooManyOperations(pos) | Self::ErrorTooManyModules(pos) | Self::ErrorStackOverflow(pos) - | Self::ErrorDataTooLarge(_, pos) - | Self::ErrorTerminated(_, pos) - | Self::ErrorCustomSyntax(_, _, pos) - | Self::ErrorRuntime(_, pos) - | Self::LoopBreak(_, pos) - | Self::Return(_, pos) => *pos = new_position, + | Self::ErrorDataTooLarge(.., pos) + | Self::ErrorTerminated(.., pos) + | Self::ErrorCustomSyntax(.., pos) + | Self::ErrorRuntime(.., pos) + | Self::LoopBreak(.., pos) + | Self::Return(.., pos) => *pos = new_position, } self } diff --git a/src/types/parse_error.rs b/src/types/parse_error.rs index d416043b..4ae403ba 100644 --- a/src/types/parse_error.rs +++ b/src/types/parse_error.rs @@ -52,7 +52,7 @@ impl fmt::Display for LexError { Self::ImproperSymbol(s, d) if d.is_empty() => { write!(f, "Invalid symbol encountered: '{}'", s) } - Self::ImproperSymbol(_, d) => f.write_str(d), + Self::ImproperSymbol(.., d) => f.write_str(d), } } } diff --git a/src/types/scope.rs b/src/types/scope.rs index 2f275b00..74a667e7 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -310,7 +310,7 @@ impl Scope<'_> { #[inline] #[must_use] pub fn contains(&self, name: &str) -> bool { - self.names.iter().any(|(key, _)| name == key) + self.names.iter().any(|(key, ..)| name == key) } /// Find an entry in the [`Scope`], starting from the last. #[inline] @@ -322,7 +322,7 @@ impl Scope<'_> { .iter() .rev() // Always search a Scope in reverse order .enumerate() - .find_map(|(i, (key, _))| { + .find_map(|(i, (key, ..))| { if name == key { let index = len - 1 - i; Some((index, self.values[index].access_mode())) @@ -352,8 +352,8 @@ impl Scope<'_> { .iter() .rev() .enumerate() - .find(|(_, (key, _))| name == key) - .and_then(|(index, _)| self.values[len - 1 - index].flatten_clone().try_cast()) + .find(|(.., (key, ..))| name == key) + .and_then(|(index, ..)| self.values[len - 1 - index].flatten_clone().try_cast()) } /// Check if the named entry in the [`Scope`] is constant. /// @@ -374,7 +374,7 @@ impl Scope<'_> { /// ``` #[inline] pub fn is_constant(&self, name: &str) -> Option { - self.get_index(name).and_then(|(_, access)| match access { + self.get_index(name).and_then(|(.., access)| match access { AccessMode::ReadWrite => None, AccessMode::ReadOnly => Some(true), }) @@ -411,7 +411,7 @@ impl Scope<'_> { value: impl Variant + Clone, ) -> &mut Self { match self.get_index(name.as_ref()) { - None | Some((_, AccessMode::ReadOnly)) => { + None | Some((.., AccessMode::ReadOnly)) => { self.push(name, value); } Some((index, AccessMode::ReadWrite)) => { @@ -453,7 +453,7 @@ impl Scope<'_> { None => { self.push(name, value); } - Some((_, AccessMode::ReadOnly)) => panic!("variable {} is constant", name.as_ref()), + Some((.., AccessMode::ReadOnly)) => panic!("variable {} is constant", name.as_ref()), Some((index, AccessMode::ReadWrite)) => { let value_ref = self.values.get_mut(index).unwrap(); *value_ref = Dynamic::from(value); @@ -511,7 +511,7 @@ impl Scope<'_> { #[cfg(not(feature = "no_module"))] #[inline] pub(crate) fn add_entry_alias(&mut self, index: usize, alias: Identifier) -> &mut Self { - let (_, aliases) = self.names.get_mut(index).unwrap(); + let (.., aliases) = self.names.get_mut(index).unwrap(); match aliases { None => { let mut list = StaticVec::new_const(); @@ -533,7 +533,7 @@ impl Scope<'_> { self.names.iter().rev().enumerate().fold( Self::new(), |mut entries, (index, (name, alias))| { - if !entries.names.iter().any(|(key, _)| key == name) { + if !entries.names.iter().any(|(key, ..)| key == name) { let orig_value = &self.values[len - 1 - index]; let mut value = orig_value.clone(); value.set_access_mode(orig_value.access_mode()); @@ -593,7 +593,7 @@ impl Scope<'_> { self.names .iter() .zip(self.values.iter()) - .map(|((name, _), value)| (name.as_ref(), value.is_read_only(), value)) + .map(|((name, ..), value)| (name.as_ref(), value.is_read_only(), value)) } /// Remove a range of entries within the [`Scope`]. /// diff --git a/tests/call_fn.rs b/tests/call_fn.rs index 0080dfcd..0efeb14c 100644 --- a/tests/call_fn.rs +++ b/tests/call_fn.rs @@ -330,7 +330,7 @@ fn test_call_fn_events() -> Result<(), Box> { "update" => engine .call_fn(scope, ast, "update", (event_data,)) .or_else(|err| match *err { - EvalAltResult::ErrorFunctionNotFound(fn_name, _) + EvalAltResult::ErrorFunctionNotFound(fn_name, ..) if fn_name.starts_with("update") => { // Default implementation of 'update' event handler diff --git a/tests/closures.rs b/tests/closures.rs index 84b270d7..8a323f97 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -251,7 +251,7 @@ fn test_closures_data_race() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataRace(_, _) + EvalAltResult::ErrorDataRace(..) )); Ok(()) diff --git a/tests/constants.rs b/tests/constants.rs index 9f3b35e0..b7df1b3a 100644 --- a/tests/constants.rs +++ b/tests/constants.rs @@ -10,13 +10,13 @@ fn test_constant() -> Result<(), Box> { *engine .eval::("const x = 123; x = 42;") .expect_err("expects error"), - EvalAltResult::ErrorParsing(ParseErrorType::AssignmentToConstant(x), _) if x == "x" + EvalAltResult::ErrorParsing(ParseErrorType::AssignmentToConstant(x), ..) if x == "x" )); #[cfg(not(feature = "no_index"))] assert!(matches!( *engine.run("const x = [1, 2, 3, 4, 5]; x[2] = 42;").expect_err("expects error"), - EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "x" + EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "x" )); Ok(()) @@ -31,7 +31,7 @@ fn test_constant_scope() -> Result<(), Box> { assert!(matches!( *engine.run_with_scope(&mut scope, "x = 1").expect_err("expects error"), - EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "x" + EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "x" )); Ok(()) @@ -87,7 +87,7 @@ fn test_constant_mut() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorAssignmentToConstant(_, _) + EvalAltResult::ErrorAssignmentToConstant(..) )); let mut scope = Scope::new(); @@ -120,7 +120,7 @@ fn test_constant_mut() -> Result<(), Box> { *engine .run_with_scope(&mut scope, "MY_NUMBER.value = 42;") .expect_err("should error"), - EvalAltResult::ErrorAssignmentToConstant(_, _) + EvalAltResult::ErrorAssignmentToConstant(..) )); Ok(()) diff --git a/tests/custom_syntax.rs b/tests/custom_syntax.rs index efaf1675..26cc2ae1 100644 --- a/tests/custom_syntax.rs +++ b/tests/custom_syntax.rs @@ -81,7 +81,7 @@ fn test_custom_syntax() -> Result<(), Box> { *engine .run("let foo = (exec [x<<15] -> { x += 2 } while x < 42) * 10;") .expect_err("should error"), - EvalAltResult::ErrorRuntime(_, _) + EvalAltResult::ErrorRuntime(..) )); assert_eq!( diff --git a/tests/data_size.rs b/tests/data_size.rs index efe6e12c..e584678e 100644 --- a/tests/data_size.rs +++ b/tests/data_size.rs @@ -38,7 +38,7 @@ fn test_max_string_size() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); #[cfg(not(feature = "no_object"))] @@ -52,7 +52,7 @@ fn test_max_string_size() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); engine.set_max_string_size(0); @@ -98,7 +98,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); #[cfg(not(feature = "no_closure"))] @@ -131,7 +131,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); assert!(matches!( @@ -143,7 +143,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); #[cfg(not(feature = "no_object"))] @@ -169,7 +169,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); assert_eq!( @@ -191,7 +191,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); #[cfg(not(feature = "no_object"))] @@ -204,7 +204,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); assert!(matches!( @@ -218,7 +218,7 @@ fn test_max_array_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); engine.set_max_array_size(0); @@ -282,7 +282,7 @@ fn test_max_map_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); assert!(matches!( @@ -295,7 +295,7 @@ fn test_max_map_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); assert!(matches!( @@ -307,7 +307,7 @@ fn test_max_map_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); #[cfg(not(feature = "no_index"))] @@ -320,7 +320,7 @@ fn test_max_map_size() -> Result<(), Box> { " ) .expect_err("should error"), - EvalAltResult::ErrorDataTooLarge(_, _) + EvalAltResult::ErrorDataTooLarge(..) )); engine.set_max_map_size(0); diff --git a/tests/eval.rs b/tests/eval.rs index 5187acf8..e57c6371 100644 --- a/tests/eval.rs +++ b/tests/eval.rs @@ -171,7 +171,7 @@ fn test_eval_disabled() -> Result<(), Box> { .compile(r#"eval("40 + 2")"#) .expect_err("should error") .0, - ParseErrorType::BadInput(LexError::ImproperSymbol(err, _)) if err == "eval" + ParseErrorType::BadInput(LexError::ImproperSymbol(err, ..)) if err == "eval" )); Ok(()) diff --git a/tests/fn_ptr.rs b/tests/fn_ptr.rs index 5b4164a3..41ad29af 100644 --- a/tests/fn_ptr.rs +++ b/tests/fn_ptr.rs @@ -73,7 +73,7 @@ fn test_fn_ptr() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(fn_name, _, err, _) + EvalAltResult::ErrorInFunctionCall(fn_name, _, err, ..) if fn_name == "foo" && matches!(*err, EvalAltResult::ErrorUnboundThis(_)) )); diff --git a/tests/functions.rs b/tests/functions.rs index a81c56a3..fb392350 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -92,8 +92,8 @@ fn test_functions_global_module() -> Result<(), Box> { foo() } ").expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(_, _, err, _) - if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, _) if v == "global::ANSWER") + EvalAltResult::ErrorInFunctionCall(.., err, _) + if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::ANSWER") )); engine.register_result_fn( @@ -110,8 +110,8 @@ fn test_functions_global_module() -> Result<(), Box> { global::LOCAL_VALUE }); ").expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(_, _, err, _) - if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, _) if v == "global::LOCAL_VALUE") + EvalAltResult::ErrorInFunctionCall(.., err, _) + if matches!(&*err, EvalAltResult::ErrorVariableNotFound(v, ..) if v == "global::LOCAL_VALUE") )); #[cfg(not(feature = "no_closure"))] diff --git a/tests/internal_fn.rs b/tests/internal_fn.rs index f4dc2ae8..62bf001d 100644 --- a/tests/internal_fn.rs +++ b/tests/internal_fn.rs @@ -170,7 +170,7 @@ fn test_function_pointers() -> Result<(), Box> { #[cfg(not(feature = "no_object"))] assert!(matches!( *engine.eval::(r#"let f = Fn("abc"); f.call(0)"#).expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("abc (") + EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("abc (") )); #[cfg(not(feature = "no_object"))] diff --git a/tests/maps.rs b/tests/maps.rs index a4757423..5dceecb4 100644 --- a/tests/maps.rs +++ b/tests/maps.rs @@ -53,7 +53,7 @@ b`: 1}; y["a\nb"] *engine .eval::("let y = #{`a${1}`: 1}; y.a1") .expect_err("should error"), - EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, _) + EvalAltResult::ErrorParsing(ParseErrorType::PropertyExpected, ..) )); assert!(engine.eval::(r#"let y = #{a: 1, b: 2, c: 3}; "c" in y"#)?); @@ -205,7 +205,7 @@ fn test_map_json() -> Result<(), Box> { assert!(matches!( *engine.parse_json(" 123", true).expect_err("should error"), - EvalAltResult::ErrorParsing(ParseErrorType::MissingToken(token, _), _) + EvalAltResult::ErrorParsing(ParseErrorType::MissingToken(token, ..), ..) if token == "{" )); diff --git a/tests/math.rs b/tests/math.rs index 25bf1228..6453c39f 100644 --- a/tests/math.rs +++ b/tests/math.rs @@ -37,37 +37,37 @@ fn test_math() -> Result<(), Box> { *engine .eval::("abs(-9223372036854775808)") .expect_err("expects negation overflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("9223372036854775807 + 1") .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("-9223372036854775808 - 1") .expect_err("expects underflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("9223372036854775807 * 9223372036854775807") .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("9223372036854775807 / 0") .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("9223372036854775807 % 0") .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); } @@ -77,31 +77,31 @@ fn test_math() -> Result<(), Box> { *engine .eval::("2147483647 + 1") .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("-2147483648 - 1") .expect_err("expects underflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("2147483647 * 2147483647") .expect_err("expects overflow"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("2147483647 / 0") .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); assert!(matches!( *engine .eval::("2147483647 % 0") .expect_err("expects division by zero"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); } } diff --git a/tests/mismatched_op.rs b/tests/mismatched_op.rs index afbf9f40..1b1f7d5e 100644 --- a/tests/mismatched_op.rs +++ b/tests/mismatched_op.rs @@ -6,7 +6,7 @@ fn test_mismatched_op() { assert!(matches!( *engine.eval::(r#""hello, " + "world!""#).expect_err("expects error"), - EvalAltResult::ErrorMismatchOutputType(need, actual, _) if need == std::any::type_name::() && actual == "string" + EvalAltResult::ErrorMismatchOutputType(need, actual, ..) if need == std::any::type_name::() && actual == "string" )); } @@ -35,18 +35,18 @@ fn test_mismatched_op_custom_type() -> Result<(), Box> { let y = new_ts(); x == y ").expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f == "== (TestStruct, TestStruct)")); + EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "== (TestStruct, TestStruct)")); assert!(!engine.eval::("new_ts() == 42")?); assert!(matches!( *engine.eval::("60 + new_ts()").expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f == format!("+ ({}, TestStruct)", std::any::type_name::()) + EvalAltResult::ErrorFunctionNotFound(f, ..) if f == format!("+ ({}, TestStruct)", std::any::type_name::()) )); assert!(matches!( *engine.eval::("42").expect_err("should error"), - EvalAltResult::ErrorMismatchOutputType(need, actual, _) + EvalAltResult::ErrorMismatchOutputType(need, actual, ..) if need == "TestStruct" && actual == std::any::type_name::() )); diff --git a/tests/modules.rs b/tests/modules.rs index db0038e7..63409844 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -237,7 +237,7 @@ fn test_module_resolver() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(fn_name, _, _, _) if fn_name == "foo" + EvalAltResult::ErrorInFunctionCall(fn_name, _, ..) if fn_name == "foo" )); engine.set_max_modules(1000); @@ -369,7 +369,7 @@ fn test_module_from_ast() -> Result<(), Box> { *engine .run(r#"import "testing" as ttt; ttt::hidden()"#) .expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "ttt::hidden ()" + EvalAltResult::ErrorFunctionNotFound(fn_name, ..) if fn_name == "ttt::hidden ()" )); Ok(()) @@ -381,13 +381,13 @@ fn test_module_export() -> Result<(), Box> { assert!(matches!( engine.compile("let x = 10; { export x; }").expect_err("should error"), - ParseError(x, _) if *x == ParseErrorType::WrongExport + ParseError(x, ..) if *x == ParseErrorType::WrongExport )); #[cfg(not(feature = "no_function"))] assert!(matches!( engine.compile("fn abc(x) { export x; }").expect_err("should error"), - ParseError(x, _) if *x == ParseErrorType::WrongExport + ParseError(x, ..) if *x == ParseErrorType::WrongExport )); Ok(()) diff --git a/tests/operations.rs b/tests/operations.rs index 8f31530f..b5b73ebd 100644 --- a/tests/operations.rs +++ b/tests/operations.rs @@ -138,7 +138,7 @@ fn test_max_operations_eval() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(_, _, err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_)) + EvalAltResult::ErrorInFunctionCall(.., err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_)) )); Ok(()) @@ -163,7 +163,7 @@ fn test_max_operations_progress() -> Result<(), Box> { *engine .run("for x in 0..500 {}") .expect_err("should error"), - EvalAltResult::ErrorTerminated(x, _) if x.as_int()? == 42 + EvalAltResult::ErrorTerminated(x, ..) if x.as_int()? == 42 )); Ok(()) diff --git a/tests/ops.rs b/tests/ops.rs index df5be33c..1077284c 100644 --- a/tests/ops.rs +++ b/tests/ops.rs @@ -27,12 +27,12 @@ fn test_ops_other_number_types() -> Result<(), Box> { assert!(matches!( *engine.eval_with_scope::(&mut scope, "x == 42").expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("== (u16,") + EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("== (u16,") )); #[cfg(not(feature = "no_float"))] assert!(matches!( *engine.eval_with_scope::(&mut scope, "x == 42.0").expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with("== (u16,") + EvalAltResult::ErrorFunctionNotFound(f, ..) if f.starts_with("== (u16,") )); assert!(!engine.eval_with_scope::(&mut scope, r#"x == "hello""#)?); diff --git a/tests/plugins.rs b/tests/plugins.rs index 5d0099f2..e0a0d648 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -93,7 +93,7 @@ fn test_plugins_package() -> Result<(), Box> { assert!( matches!(*engine.run("const A = [1, 2, 3]; A.test(42);").expect_err("should error"), - EvalAltResult::ErrorAssignmentToConstant(x, _) if x == "array") + EvalAltResult::ErrorAssignmentToConstant(x, ..) if x == "array") ) } diff --git a/tests/string.rs b/tests/string.rs index ac7991f3..c569b880 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -117,7 +117,7 @@ fn test_string_mut() -> Result<(), Box> { assert_eq!(engine.eval::(r#"bar("hello")"#)?, 5); assert!( matches!(*engine.eval::(r#"baz("hello")"#).expect_err("should error"), - EvalAltResult::ErrorFunctionNotFound(f, _) if f == "baz (&str | ImmutableString | String)" + EvalAltResult::ErrorFunctionNotFound(f, ..) if f == "baz (&str | ImmutableString | String)" ) ); diff --git a/tests/throw.rs b/tests/throw.rs index 79bd2424..caf2fed9 100644 --- a/tests/throw.rs +++ b/tests/throw.rs @@ -6,12 +6,12 @@ fn test_throw() { assert!(matches!( *engine.run("if true { throw 42 }").expect_err("expects error"), - EvalAltResult::ErrorRuntime(s, _) if s.as_int().unwrap() == 42 + EvalAltResult::ErrorRuntime(s, ..) if s.as_int().unwrap() == 42 )); assert!(matches!( *engine.run(r#"throw"#).expect_err("expects error"), - EvalAltResult::ErrorRuntime(s, _) if s.is::<()>() + EvalAltResult::ErrorRuntime(s, ..) if s.is::<()>() )); } @@ -96,7 +96,7 @@ fn test_try_catch() -> Result<(), Box> { *engine .run("try { 42/0; } catch { throw; }") .expect_err("expects error"), - EvalAltResult::ErrorArithmetic(_, _) + EvalAltResult::ErrorArithmetic(..) )); Ok(()) diff --git a/tests/var_scope.rs b/tests/var_scope.rs index b8d4824d..d8543b81 100644 --- a/tests/var_scope.rs +++ b/tests/var_scope.rs @@ -115,7 +115,7 @@ fn test_var_resolver() -> Result<(), Box> { assert_eq!(engine.eval_with_scope::(&mut scope, "chameleon")?, 1); assert!( matches!(*engine.eval_with_scope::(&mut scope, "DO_NOT_USE").expect_err("should error"), - EvalAltResult::ErrorVariableNotFound(n, _) if n == "DO_NOT_USE") + EvalAltResult::ErrorVariableNotFound(n, ..) if n == "DO_NOT_USE") ); Ok(()) From 97a8fd3d5b1143ec9334e740ec740b9987597220 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 09:25:53 +0800 Subject: [PATCH 08/12] Improve reify syntax. --- src/api/custom_syntax.rs | 20 +-- src/func/call.rs | 14 +- src/func/register.rs | 25 ++-- src/reify.rs | 17 ++- src/types/dynamic.rs | 282 +++++++++++++++++++-------------------- 5 files changed, 184 insertions(+), 174 deletions(-) diff --git a/src/api/custom_syntax.rs b/src/api/custom_syntax.rs index c0f15ff4..01e0d523 100644 --- a/src/api/custom_syntax.rs +++ b/src/api/custom_syntax.rs @@ -72,8 +72,8 @@ impl Expression<'_> { pub fn get_string_value(&self) -> Option<&str> { match self.0 { #[cfg(not(feature = "no_module"))] - Expr::Variable(.., _, x) if x.1.is_some() => None, - Expr::Variable(.., _, x) => Some(x.2.as_str()), + Expr::Variable(.., x) if x.1.is_some() => None, + Expr::Variable(.., x) => Some(x.2.as_str()), Expr::StringConstant(x, ..) => Some(x.as_str()), _ => None, } @@ -94,19 +94,19 @@ impl Expression<'_> { pub fn get_literal_value(&self) -> Option { // Coded this way in order to maximally leverage potentials for dead-code removal. match self.0 { - Expr::IntegerConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), + Expr::IntegerConstant(x, ..) => reify!(*x => Option), #[cfg(not(feature = "no_float"))] - Expr::FloatConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), + Expr::FloatConstant(x, ..) => reify!(*x => Option), - Expr::CharConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), - Expr::StringConstant(x, ..) => reify!(x.clone(), |x: T| Some(x), || None), - Expr::Variable(.., _, x) => { + Expr::CharConstant(x, ..) => reify!(*x => Option), + Expr::StringConstant(x, ..) => reify!(x.clone() => Option), + Expr::Variable(.., x) => { let x: ImmutableString = x.2.clone().into(); - reify!(x, |x: T| Some(x), || None) + reify!(x => Option) } - Expr::BoolConstant(x, ..) => reify!(*x, |x: T| Some(x), || None), - Expr::Unit(_) => reify!((), |x: T| Some(x), || None), + Expr::BoolConstant(x, ..) => reify!(*x => Option), + Expr::Unit(..) => reify!(() => Option), _ => None, } diff --git a/src/func/call.rs b/src/func/call.rs index 56311890..bb19eda7 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -46,11 +46,13 @@ impl<'a> ArgBackup<'a> { /// This function replaces the first argument of a method call with a clone copy. /// This is to prevent a pure function unintentionally consuming the first argument. /// - /// `restore_first_arg` must be called before the end of the scope to prevent the shorter lifetime from leaking. + /// `restore_first_arg` must be called before the end of the scope to prevent the shorter + /// lifetime from leaking. /// /// # Safety /// - /// This method blindly casts a reference to another lifetime, which saves allocation and string cloning. + /// This method blindly casts a reference to another lifetime, which saves allocation and + /// string cloning. /// /// As long as `restore_first_arg` is called before the end of the scope, the shorter lifetime /// will not leak. @@ -71,8 +73,8 @@ impl<'a> ArgBackup<'a> { // Blindly casting a reference to another lifetime saves allocation and string cloning, // but must be used with the utmost care. // - // We can do this here because, before the end of this scope, we'd restore the original reference - // via `restore_first_arg`. Therefore this shorter lifetime does not leak. + // We can do this here because, before the end of this scope, we'd restore the original + // reference via `restore_first_arg`. Therefore this shorter lifetime does not leak. self.orig_mut = Some(mem::replace(&mut args[0], unsafe { mem::transmute(&mut self.value_copy) })); @@ -81,8 +83,8 @@ impl<'a> ArgBackup<'a> { /// /// # Safety /// - /// If `change_first_arg_to_copy` has been called, this function **MUST** be called _BEFORE_ exiting - /// the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak. + /// If `change_first_arg_to_copy` has been called, this function **MUST** be called _BEFORE_ + /// exiting the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak. #[inline(always)] fn restore_first_arg(mut self, args: &mut FnCallArgs<'a>) { if let Some(p) = self.orig_mut.take() { diff --git a/src/func/register.rs b/src/func/register.rs index b87e0bec..eab4000d 100644 --- a/src/func/register.rs +++ b/src/func/register.rs @@ -38,25 +38,26 @@ pub fn by_ref(data: &mut Dynamic) -> DynamicWriteLock { } /// Dereference into value. -#[inline] +#[inline(always)] #[must_use] pub fn by_value(data: &mut Dynamic) -> T { if TypeId::of::() == TypeId::of::<&str>() { // If T is `&str`, data must be `ImmutableString`, so map directly to it data.flatten_in_place(); let ref_str = data.as_str_ref().expect("&str"); - //let ref_t = reify!(&ref_str, |ref_t: &T| ref_t, || unreachable!()); - let ref_t = unsafe { mem::transmute::<_, &T>(&ref_str) }; - ref_t.clone() - } else if TypeId::of::() == TypeId::of::() { - // If T is `String`, data must be `ImmutableString`, so map directly to it - let t = mem::take(data).into_string().expect("`ImmutableString`"); - reify!(t, |t: T| t, || unreachable!()) - } else { - // We consume the argument and then replace it with () - the argument is not supposed to be used again. - // This way, we avoid having to clone the argument again, because it is already a clone when passed here. - mem::take(data).cast::() + // # Safety + // + // We already checked that `T` is `&str`, so it is safe to cast here. + return unsafe { std::mem::transmute_copy::<_, T>(&ref_str) }; } + if TypeId::of::() == TypeId::of::() { + // If T is `String`, data must be `ImmutableString`, so map directly to it + return reify!(mem::take(data).into_string().expect("`ImmutableString`") => T); + } + + // We consume the argument and then replace it with () - the argument is not supposed to be used again. + // This way, we avoid having to clone the argument again, because it is already a clone when passed here. + return mem::take(data).cast::(); } /// Trait to register custom Rust functions. diff --git a/src/reify.rs b/src/reify.rs index e0ac8481..e582b5cb 100644 --- a/src/reify.rs +++ b/src/reify.rs @@ -4,9 +4,6 @@ #[macro_export] macro_rules! reify { ($old:ident, |$new:ident : $t:ty| $code:expr, || $fallback:expr) => {{ - #[allow(unused_imports)] - use std::any::Any; - if std::any::TypeId::of::<$t>() == std::any::Any::type_id(&$old) { // SAFETY: This is safe because we check to make sure the two types are // actually the same type. @@ -26,4 +23,18 @@ macro_rules! reify { ($old:expr, |$new:ident : $t:ty| $code:expr) => { reify!($old, |$new: $t| $code, || ()) }; + + ($old:ident => Option<$t:ty>) => { + reify!($old, |v: $t| Some(v), || None) + }; + ($old:expr => Option<$t:ty>) => { + reify!($old, |v: $t| Some(v), || None) + }; + + ($old:ident => $t:ty) => { + reify!($old, |v: $t| v, || unreachable!()) + }; + ($old:expr => $t:ty) => { + reify!($old, |v: $t| v, || unreachable!()) + }; } diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index d0a4d56a..08a89729 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -399,15 +399,15 @@ impl Dynamic { #[cfg(not(feature = "no_std"))] Union::TimeStamp(..) => TypeId::of::(), - Union::Variant(ref v, _, ..) => (***v).type_id(), + Union::Variant(ref v, ..) => (***v).type_id(), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => (*cell.borrow()).type_id(), + Union::Shared(ref cell, ..) => (*cell.borrow()).type_id(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_id(), + Union::Shared(ref cell, ..) => (*cell.read().unwrap()).type_id(), } } /// Get the name of the type of the value held by this [`Dynamic`]. @@ -438,17 +438,17 @@ impl Dynamic { #[cfg(not(feature = "no_std"))] Union::TimeStamp(..) => "timestamp", - Union::Variant(ref v, _, ..) => (***v).type_name(), + Union::Variant(ref v, ..) => (***v).type_name(), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => cell + Union::Shared(ref cell, ..) => cell .try_borrow() .map(|v| (*v).type_name()) .unwrap_or(""), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).type_name(), + Union::Shared(ref cell, ..) => (*cell.read().unwrap()).type_name(), } } } @@ -464,31 +464,31 @@ impl Hash for Dynamic { match self.0 { Union::Unit(..) => ().hash(state), - Union::Bool(ref b, _, ..) => b.hash(state), - Union::Str(ref s, _, ..) => s.hash(state), - Union::Char(ref c, _, ..) => c.hash(state), - Union::Int(ref i, _, ..) => i.hash(state), + Union::Bool(ref b, ..) => b.hash(state), + Union::Str(ref s, ..) => s.hash(state), + Union::Char(ref c, ..) => c.hash(state), + Union::Int(ref i, ..) => i.hash(state), #[cfg(not(feature = "no_float"))] - Union::Float(ref f, _, ..) => f.hash(state), + Union::Float(ref f, ..) => f.hash(state), #[cfg(feature = "decimal")] - Union::Decimal(ref d, _, ..) => d.hash(state), + Union::Decimal(ref d, ..) => d.hash(state), #[cfg(not(feature = "no_index"))] - Union::Array(ref a, _, ..) => a.as_ref().hash(state), + Union::Array(ref a, ..) => a.as_ref().hash(state), #[cfg(not(feature = "no_index"))] - Union::Blob(ref a, _, ..) => a.as_ref().hash(state), + Union::Blob(ref a, ..) => a.as_ref().hash(state), #[cfg(not(feature = "no_object"))] - Union::Map(ref m, _, ..) => m.as_ref().hash(state), - Union::FnPtr(ref f, _, ..) => f.hash(state), + Union::Map(ref m, ..) => m.as_ref().hash(state), + Union::FnPtr(ref f, ..) => f.hash(state), #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => (*cell.borrow()).hash(state), + Union::Shared(ref cell, ..) => (*cell.borrow()).hash(state), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => (*cell.read().unwrap()).hash(state), + Union::Shared(ref cell, ..) => (*cell.read().unwrap()).hash(state), - Union::Variant(ref v, _, ..) => { + Union::Variant(ref v, ..) => { let _v = v; #[cfg(not(feature = "only_i32"))] @@ -546,25 +546,25 @@ impl fmt::Display for Dynamic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.0 { Union::Unit(..) => write!(f, ""), - Union::Bool(ref v, _, ..) => fmt::Display::fmt(v, f), - Union::Str(ref v, _, ..) => fmt::Display::fmt(v, f), - Union::Char(ref v, _, ..) => fmt::Display::fmt(v, f), - Union::Int(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Bool(ref v, ..) => fmt::Display::fmt(v, f), + Union::Str(ref v, ..) => fmt::Display::fmt(v, f), + Union::Char(ref v, ..) => fmt::Display::fmt(v, f), + Union::Int(ref v, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_float"))] - Union::Float(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Float(ref v, ..) => fmt::Display::fmt(v, f), #[cfg(feature = "decimal")] - Union::Decimal(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::Decimal(ref v, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_index"))] Union::Array(..) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_index"))] Union::Blob(..) => fmt::Debug::fmt(self, f), #[cfg(not(feature = "no_object"))] Union::Map(..) => fmt::Debug::fmt(self, f), - Union::FnPtr(ref v, _, ..) => fmt::Display::fmt(v, f), + Union::FnPtr(ref v, ..) => fmt::Display::fmt(v, f), #[cfg(not(feature = "no_std"))] Union::TimeStamp(..) => f.write_str(""), - Union::Variant(ref v, _, ..) => { + Union::Variant(ref v, ..) => { let _value_any = (***v).as_any(); let _type_id = _value_any.type_id(); @@ -621,7 +621,7 @@ impl fmt::Display for Dynamic { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { if let Ok(v) = cell.try_borrow() { fmt::Display::fmt(&*v, f) } else { @@ -630,7 +630,7 @@ impl fmt::Display for Dynamic { } #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => fmt::Display::fmt(&*cell.read().unwrap(), f), + Union::Shared(ref cell, ..) => fmt::Display::fmt(&*cell.read().unwrap(), f), } } } @@ -638,19 +638,19 @@ impl fmt::Display for Dynamic { impl fmt::Debug for Dynamic { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.0 { - Union::Unit(ref v, _, ..) => fmt::Debug::fmt(v, f), - Union::Bool(ref v, _, ..) => fmt::Debug::fmt(v, f), - Union::Str(ref v, _, ..) => fmt::Debug::fmt(v, f), - Union::Char(ref v, _, ..) => fmt::Debug::fmt(v, f), - Union::Int(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Unit(ref v, ..) => fmt::Debug::fmt(v, f), + Union::Bool(ref v, ..) => fmt::Debug::fmt(v, f), + Union::Str(ref v, ..) => fmt::Debug::fmt(v, f), + Union::Char(ref v, ..) => fmt::Debug::fmt(v, f), + Union::Int(ref v, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_float"))] - Union::Float(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Float(ref v, ..) => fmt::Debug::fmt(v, f), #[cfg(feature = "decimal")] - Union::Decimal(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Decimal(ref v, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_index"))] - Union::Array(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::Array(ref v, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_index"))] - Union::Blob(ref v, _, ..) => { + Union::Blob(ref v, ..) => { f.write_str("[")?; v.iter().enumerate().try_for_each(|(i, v)| { if i > 0 && i % 8 == 0 { @@ -661,15 +661,15 @@ impl fmt::Debug for Dynamic { f.write_str("]") } #[cfg(not(feature = "no_object"))] - Union::Map(ref v, _, ..) => { + Union::Map(ref v, ..) => { f.write_str("#")?; fmt::Debug::fmt(v, f) } - Union::FnPtr(ref v, _, ..) => fmt::Debug::fmt(v, f), + Union::FnPtr(ref v, ..) => fmt::Debug::fmt(v, f), #[cfg(not(feature = "no_std"))] Union::TimeStamp(..) => write!(f, ""), - Union::Variant(ref v, _, ..) => { + Union::Variant(ref v, ..) => { let _value_any = (***v).as_any(); let _type_id = _value_any.type_id(); @@ -726,7 +726,7 @@ impl fmt::Debug for Dynamic { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { if let Ok(v) = cell.try_borrow() { write!(f, "{:?} (shared)", *v) } else { @@ -735,7 +735,7 @@ impl fmt::Debug for Dynamic { } #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => fmt::Debug::fmt(&*cell.read().unwrap(), f), + Union::Shared(ref cell, ..) => fmt::Debug::fmt(&*cell.read().unwrap(), f), } } } @@ -1010,43 +1010,43 @@ impl Dynamic { #[must_use] pub(crate) const fn access_mode(&self) -> AccessMode { match self.0 { - Union::Unit(.., _, access) - | Union::Bool(.., _, access) - | Union::Str(.., _, access) - | Union::Char(.., _, access) - | Union::Int(.., _, access) - | Union::FnPtr(.., _, access) - | Union::Variant(.., _, access) => access, + Union::Unit(.., access) + | Union::Bool(.., access) + | Union::Str(.., access) + | Union::Char(.., access) + | Union::Int(.., access) + | Union::FnPtr(.., access) + | Union::Variant(.., access) => access, #[cfg(not(feature = "no_float"))] - Union::Float(.., _, access) => access, + Union::Float(.., access) => access, #[cfg(feature = "decimal")] - Union::Decimal(.., _, access) => access, + Union::Decimal(.., access) => access, #[cfg(not(feature = "no_index"))] - Union::Array(.., _, access) | Union::Blob(.., _, access) => access, + Union::Array(.., access) | Union::Blob(.., access) => access, #[cfg(not(feature = "no_object"))] - Union::Map(.., _, access) => access, + Union::Map(.., access) => access, #[cfg(not(feature = "no_std"))] - Union::TimeStamp(.., _, access) => access, + Union::TimeStamp(.., access) => access, #[cfg(not(feature = "no_closure"))] - Union::Shared(.., _, access) => access, + Union::Shared(.., access) => access, } } /// Set the [`AccessMode`] for this [`Dynamic`]. pub(crate) fn set_access_mode(&mut self, typ: AccessMode) -> &mut Self { match self.0 { - Union::Unit(.., _, ref mut access) - | Union::Bool(.., _, ref mut access) - | Union::Str(.., _, ref mut access) - | Union::Char(.., _, ref mut access) - | Union::Int(.., _, ref mut access) - | Union::FnPtr(.., _, ref mut access) - | Union::Variant(.., _, ref mut access) => *access = typ, + Union::Unit(.., ref mut access) + | Union::Bool(.., ref mut access) + | Union::Str(.., ref mut access) + | Union::Char(.., ref mut access) + | Union::Int(.., ref mut access) + | Union::FnPtr(.., ref mut access) + | Union::Variant(.., ref mut access) => *access = typ, #[cfg(not(feature = "no_float"))] - Union::Float(.., _, ref mut access) => *access = typ, + Union::Float(.., ref mut access) => *access = typ, #[cfg(feature = "decimal")] - Union::Decimal(.., _, ref mut access) => *access = typ, + Union::Decimal(.., ref mut access) => *access = typ, #[cfg(not(feature = "no_index"))] Union::Array(ref mut a, _, ref mut access) => { *access = typ; @@ -1055,7 +1055,7 @@ impl Dynamic { } } #[cfg(not(feature = "no_index"))] - Union::Blob(.., _, ref mut access) => *access = typ, + Union::Blob(.., ref mut access) => *access = typ, #[cfg(not(feature = "no_object"))] Union::Map(ref mut m, _, ref mut access) => { *access = typ; @@ -1064,9 +1064,9 @@ impl Dynamic { } } #[cfg(not(feature = "no_std"))] - Union::TimeStamp(.., _, ref mut access) => *access = typ, + Union::TimeStamp(.., ref mut access) => *access = typ, #[cfg(not(feature = "no_closure"))] - Union::Shared(.., _, ref mut access) => *access = typ, + Union::Shared(.., ref mut access) => *access = typ, } self } @@ -1081,17 +1081,17 @@ impl Dynamic { pub fn is_read_only(&self) -> bool { #[cfg(not(feature = "no_closure"))] match self.0 { - Union::Shared(.., _, ReadOnly) => return true, + Union::Shared(.., ReadOnly) => return true, #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { return match cell.borrow().access_mode() { ReadWrite => false, ReadOnly => true, } } #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { return match cell.read().unwrap().access_mode() { ReadWrite => false, ReadOnly => true, @@ -1125,11 +1125,11 @@ impl Dynamic { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => cell.borrow().is_hashable(), + Union::Shared(ref cell, ..) => cell.borrow().is_hashable(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => cell.read().unwrap().is_hashable(), + Union::Shared(ref cell, ..) => cell.read().unwrap().is_hashable(), _ => false, } @@ -1273,33 +1273,29 @@ impl Dynamic { reify!(self, |v: T| return Some(v)); match self.0 { - Union::Int(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Int(v, ..) => reify!(v => Option), #[cfg(not(feature = "no_float"))] - Union::Float(v, ..) => reify!(*v, |v: T| Some(v), || None), + Union::Float(v, ..) => reify!(*v => Option), #[cfg(feature = "decimal")] - Union::Decimal(v, ..) => reify!(*v, |v: T| Some(v), || None), - Union::Bool(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Decimal(v, ..) => reify!(*v => Option), + Union::Bool(v, ..) => reify!(v => Option), Union::Str(v, ..) => { - reify!(v, |v: T| Some(v), || { - reify!(v.to_string(), |v: T| Some(v), || None) - }) + reify!(v, |v: T| Some(v), || reify!(v.to_string() => Option)) } - Union::Char(v, ..) => reify!(v, |v: T| Some(v), || None), + Union::Char(v, ..) => reify!(v => Option), #[cfg(not(feature = "no_index"))] - Union::Array(v, ..) => reify!(v, |v: Box| Some(*v), || None), + Union::Array(v, ..) => reify!(*v => Option), #[cfg(not(feature = "no_index"))] - Union::Blob(v, ..) => reify!(v, |v: Box| Some(*v), || None), + Union::Blob(v, ..) => reify!(*v => Option), #[cfg(not(feature = "no_object"))] - Union::Map(v, ..) => reify!(v, |v: Box| Some(*v), || None), - Union::FnPtr(v, ..) => reify!(v, |v: Box| Some(*v), || None), + Union::Map(v, ..) => reify!(*v => Option), + Union::FnPtr(v, ..) => reify!(*v => Option), #[cfg(not(feature = "no_std"))] - Union::TimeStamp(v, ..) => reify!(v, |v: Box| Some(*v), || None), - Union::Unit(..) => reify!((), |v: T| Some(v), || None), - Union::Variant(v, _, ..) => (*v).as_boxed_any().downcast().ok().map(|x| *x), + Union::TimeStamp(v, ..) => reify!(*v => Option), + Union::Unit(v, ..) => reify!(v => Option), + Union::Variant(v, ..) => (*v).as_boxed_any().downcast().ok().map(|x| *x), #[cfg(not(feature = "no_closure"))] - Union::Shared(..) => { - unreachable!("Union::Shared case should be already handled") - } + Union::Shared(..) => unreachable!("Union::Shared case should be already handled"), } } /// Convert the [`Dynamic`] value into a specific type. @@ -1384,10 +1380,10 @@ impl Dynamic { match self.0 { #[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "sync"))] - Union::Shared(ref cell, _, ..) => cell.borrow().clone(), + Union::Shared(ref cell, ..) => cell.borrow().clone(), #[cfg(not(feature = "no_closure"))] #[cfg(feature = "sync")] - Union::Shared(ref cell, _, ..) => cell.read().unwrap().clone(), + Union::Shared(ref cell, ..) => cell.read().unwrap().clone(), _ => self.clone(), } } @@ -1402,7 +1398,7 @@ impl Dynamic { pub fn flatten(self) -> Self { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, ..) => crate::func::native::shared_try_take(cell).map_or_else( + Union::Shared(cell, ..) => crate::func::native::shared_try_take(cell).map_or_else( #[cfg(not(feature = "sync"))] |cell| cell.borrow().clone(), #[cfg(feature = "sync")] @@ -1425,7 +1421,7 @@ impl Dynamic { pub(crate) fn flatten_in_place(&mut self) -> &mut Self { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref mut cell, _, ..) => { + Union::Shared(ref mut cell, ..) => { let cell = mem::take(cell); *self = crate::func::native::shared_try_take(cell).map_or_else( #[cfg(not(feature = "sync"))] @@ -1457,7 +1453,7 @@ impl Dynamic { pub fn is_locked(&self) -> bool { #[cfg(not(feature = "no_closure"))] match self.0 { - Union::Shared(ref _cell, _, ..) => { + Union::Shared(ref _cell, ..) => { #[cfg(not(feature = "sync"))] return _cell.try_borrow().is_err(); #[cfg(feature = "sync")] @@ -1482,7 +1478,7 @@ impl Dynamic { pub fn read_lock(&self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] @@ -1517,7 +1513,7 @@ impl Dynamic { pub fn write_lock(&mut self) -> Option> { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, _, ..) => { + Union::Shared(ref cell, ..) => { let guard = crate::func::native::locked_write(cell); if (*guard).type_id() != TypeId::of::() @@ -1546,79 +1542,79 @@ impl Dynamic { if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Int(ref v, _, ..) => v.as_any().downcast_ref::(), + Union::Int(ref v, ..) => v.as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_float"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Float(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::Float(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(feature = "decimal")] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Decimal(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::Decimal(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Bool(ref v, _, ..) => v.as_any().downcast_ref::(), + Union::Bool(ref v, ..) => v.as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(ref v, _, ..) => v.as_any().downcast_ref::(), + Union::Str(ref v, ..) => v.as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Char(ref v, _, ..) => v.as_any().downcast_ref::(), + Union::Char(ref v, ..) => v.as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Array(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::Array(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Blob(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::Blob(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_object"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Map(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::Map(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::FnPtr(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::FnPtr(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } #[cfg(not(feature = "no_std"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::TimeStamp(ref v, _, ..) => v.as_ref().as_any().downcast_ref::(), + Union::TimeStamp(ref v, ..) => v.as_ref().as_any().downcast_ref::(), _ => None, }; } if TypeId::of::() == TypeId::of::<()>() { return match self.0 { - Union::Unit(ref v, _, ..) => v.as_any().downcast_ref::(), + Union::Unit(ref v, ..) => v.as_any().downcast_ref::(), _ => None, }; } @@ -1627,7 +1623,7 @@ impl Dynamic { } match self.0 { - Union::Variant(ref v, _, ..) => (***v).as_any().downcast_ref::(), + Union::Variant(ref v, ..) => (***v).as_any().downcast_ref::(), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => None, _ => None, @@ -1644,79 +1640,79 @@ impl Dynamic { if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Int(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), + Union::Int(ref mut v, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_float"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Float(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Float(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(feature = "decimal")] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Decimal(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Decimal(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Bool(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), + Union::Bool(ref mut v, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Str(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), + Union::Str(ref mut v, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Char(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), + Union::Char(ref mut v, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Array(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Array(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_index"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Blob(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Blob(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_object"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::Map(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::Map(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::FnPtr(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::FnPtr(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } #[cfg(not(feature = "no_std"))] if TypeId::of::() == TypeId::of::() { return match self.0 { - Union::TimeStamp(ref mut v, _, ..) => v.as_mut().as_any_mut().downcast_mut::(), + Union::TimeStamp(ref mut v, ..) => v.as_mut().as_any_mut().downcast_mut::(), _ => None, }; } if TypeId::of::() == TypeId::of::<()>() { return match self.0 { - Union::Unit(ref mut v, _, ..) => v.as_any_mut().downcast_mut::(), + Union::Unit(ref mut v, ..) => v.as_any_mut().downcast_mut::(), _ => None, }; } @@ -1725,7 +1721,7 @@ impl Dynamic { } match self.0 { - Union::Variant(ref mut v, _, ..) => (***v).as_any_mut().downcast_mut::(), + Union::Variant(ref mut v, ..) => (***v).as_any_mut().downcast_mut::(), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => None, _ => None, @@ -1736,7 +1732,7 @@ impl Dynamic { #[inline] pub fn as_unit(&self) -> Result<(), &'static str> { match self.0 { - Union::Unit(v, _, ..) => Ok(v), + Union::Unit(v, ..) => Ok(v), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1747,7 +1743,7 @@ impl Dynamic { #[inline] pub fn as_int(&self) -> Result { match self.0 { - Union::Int(n, _, ..) => Ok(n), + Union::Int(n, ..) => Ok(n), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1761,7 +1757,7 @@ impl Dynamic { #[inline] pub fn as_float(&self) -> Result { match self.0 { - Union::Float(n, _, ..) => Ok(*n), + Union::Float(n, ..) => Ok(*n), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1775,7 +1771,7 @@ impl Dynamic { #[inline] pub fn as_decimal(&self) -> Result { match self.0 { - Union::Decimal(ref n, _, ..) => Ok(**n), + Union::Decimal(ref n, ..) => Ok(**n), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1786,7 +1782,7 @@ impl Dynamic { #[inline] pub fn as_bool(&self) -> Result { match self.0 { - Union::Bool(b, _, ..) => Ok(b), + Union::Bool(b, ..) => Ok(b), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1797,7 +1793,7 @@ impl Dynamic { #[inline] pub fn as_char(&self) -> Result { match self.0 { - Union::Char(n, _, ..) => Ok(n), + Union::Char(n, ..) => Ok(n), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => self.read_lock().map(|v| *v).ok_or_else(|| self.type_name()), _ => Err(self.type_name()), @@ -1812,7 +1808,7 @@ impl Dynamic { #[inline] pub(crate) fn as_str_ref(&self) -> Result<&str, &'static str> { match self.0 { - Union::Str(ref s, _, ..) => Ok(s), + Union::Str(ref s, ..) => Ok(s), #[cfg(not(feature = "no_closure"))] Union::Shared(..) => panic!("as_str_ref() cannot be called on shared values"), _ => Err(self.type_name()), @@ -1831,16 +1827,16 @@ impl Dynamic { #[inline] pub fn into_immutable_string(self) -> Result { match self.0 { - Union::Str(s, _, ..) => Ok(s), + Union::Str(s, ..) => Ok(s), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, ..) => { + Union::Shared(cell, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Str(ref s, _, ..) => Ok(s.clone()), + Union::Str(ref s, ..) => Ok(s.clone()), _ => Err((*value).type_name()), } } @@ -1853,16 +1849,16 @@ impl Dynamic { #[inline(always)] pub fn into_array(self) -> Result { match self.0 { - Union::Array(a, _, ..) => Ok(*a), + Union::Array(a, ..) => Ok(*a), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, ..) => { + Union::Shared(cell, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Array(ref a, _, ..) => Ok(a.as_ref().clone()), + Union::Array(ref a, ..) => Ok(a.as_ref().clone()), _ => Err((*value).type_name()), } } @@ -1875,7 +1871,7 @@ impl Dynamic { #[inline(always)] pub fn into_typed_array(self) -> Result, &'static str> { match self.0 { - Union::Array(a, _, ..) => a + Union::Array(a, ..) => a .into_iter() .map(|v| { #[cfg(not(feature = "no_closure"))] @@ -1893,14 +1889,14 @@ impl Dynamic { .collect(), Union::Blob(..) if TypeId::of::() == TypeId::of::() => Ok(self.cast::>()), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, ..) => { + Union::Shared(cell, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Array(ref a, _, ..) => { + Union::Array(ref a, ..) => { a.iter() .map(|v| { #[cfg(not(feature = "no_closure"))] @@ -1932,16 +1928,16 @@ impl Dynamic { #[inline(always)] pub fn into_blob(self) -> Result { match self.0 { - Union::Blob(a, _, ..) => Ok(*a), + Union::Blob(a, ..) => Ok(*a), #[cfg(not(feature = "no_closure"))] - Union::Shared(cell, _, ..) => { + Union::Shared(cell, ..) => { #[cfg(not(feature = "sync"))] let value = cell.borrow(); #[cfg(feature = "sync")] let value = cell.read().unwrap(); match value.0 { - Union::Blob(ref a, _, ..) => Ok(a.as_ref().clone()), + Union::Blob(ref a, ..) => Ok(a.as_ref().clone()), _ => Err((*value).type_name()), } } From 7686ca619a376df315c31596dbdd9e5dc0f5bbd7 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 09:46:14 +0800 Subject: [PATCH 09/12] Use .. for (_). --- codegen/src/function.rs | 18 ++++----- codegen/src/module.rs | 18 +++++---- codegen/src/rhai_module.rs | 6 +-- src/api/mod.rs | 2 +- src/ast/ast.rs | 6 +-- src/ast/expr.rs | 12 +++--- src/ast/stmt.rs | 22 +++++------ src/eval/chaining.rs | 4 +- src/eval/debugger.rs | 8 ++-- src/eval/expr.rs | 2 +- src/eval/stmt.rs | 4 +- src/eval/target.rs | 10 ++--- src/func/call.rs | 2 +- src/func/callable_function.rs | 70 +++++++++++++++++------------------ src/optimizer.rs | 10 ++--- src/parser.rs | 42 +++++++++++---------- src/tokenizer.rs | 12 +++--- src/types/error.rs | 36 +++++++++--------- tests/closures.rs | 2 +- tests/fn_ptr.rs | 2 +- tests/internal_fn.rs | 2 +- tests/modules.rs | 2 +- tests/operations.rs | 10 ++--- tests/stack.rs | 2 +- 24 files changed, 155 insertions(+), 149 deletions(-) diff --git a/codegen/src/function.rs b/codegen/src/function.rs index f0b14fd3..6cebaa03 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -366,7 +366,7 @@ impl Parse for ExportedFn { }) => { matches!(flatten_type_groups(elem.as_ref()), syn::Type::Path(ref p) if p.path == str_type_path) } - syn::Type::Verbatim(_) => false, + syn::Type::Verbatim(..) => false, _ => true, }; if !is_ok { @@ -381,13 +381,13 @@ impl Parse for ExportedFn { match fn_all.sig.output { syn::ReturnType::Type(.., ref ret_type) => { match flatten_type_groups(ret_type.as_ref()) { - syn::Type::Ptr(_) => { + syn::Type::Ptr(..) => { return Err(syn::Error::new( fn_all.sig.output.span(), "Rhai functions cannot return pointers", )) } - syn::Type::Reference(_) => { + syn::Type::Reference(..) => { return Err(syn::Error::new( fn_all.sig.output.span(), "Rhai functions cannot return references", @@ -544,28 +544,28 @@ impl ExportedFn { match params.special { // 2a. Property getters must take only the subject as an argument. - FnSpecialAccess::Property(Property::Get(_)) if self.arg_count() != 1 => { + FnSpecialAccess::Property(Property::Get(..)) if self.arg_count() != 1 => { return Err(syn::Error::new( self.signature.inputs.span(), "property getter requires exactly 1 parameter", )) } // 2b. Property getters must return a value. - FnSpecialAccess::Property(Property::Get(_)) if self.return_type().is_none() => { + FnSpecialAccess::Property(Property::Get(..)) if self.return_type().is_none() => { return Err(syn::Error::new( self.signature.span(), "property getter must return a value", )) } // 3a. Property setters must take the subject and a new value as arguments. - FnSpecialAccess::Property(Property::Set(_)) if self.arg_count() != 2 => { + FnSpecialAccess::Property(Property::Set(..)) if self.arg_count() != 2 => { return Err(syn::Error::new( self.signature.inputs.span(), "property setter requires exactly 2 parameters", )) } // 3b. Non-raw property setters must return nothing. - FnSpecialAccess::Property(Property::Set(_)) + FnSpecialAccess::Property(Property::Set(..)) if params.return_raw.is_none() && self.return_type().is_some() => { return Err(syn::Error::new( @@ -734,7 +734,7 @@ impl ExportedFn { .unwrap(), ); } - syn::FnArg::Receiver(_) => todo!("true self parameters not implemented yet"), + syn::FnArg::Receiver(..) => todo!("true self parameters not implemented yet"), } unpack_exprs.push(syn::parse2::(quote! { #var }).unwrap()); } else { @@ -811,7 +811,7 @@ impl ExportedFn { ); } } - syn::FnArg::Receiver(_) => panic!("internal error: how did this happen!?"), + syn::FnArg::Receiver(..) => panic!("internal error: how did this happen!?"), } if !is_ref { unpack_exprs.push(syn::parse2::(quote! { #var }).unwrap()); diff --git a/codegen/src/module.rs b/codegen/src/module.rs index 6942b69c..eaa43070 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -144,12 +144,14 @@ impl Parse for Module { attrs, ty, .. - }) if matches!(vis, syn::Visibility::Public(_)) => consts.push(ExportedConst { - name: ident.to_string(), - typ: ty.clone(), - expr: expr.as_ref().clone(), - cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), - }), + }) if matches!(vis, syn::Visibility::Public(..)) => { + consts.push(ExportedConst { + name: ident.to_string(), + typ: ty.clone(), + expr: expr.as_ref().clone(), + cfg_attrs: crate::attrs::collect_cfg_attr(&attrs), + }) + } _ => {} } } @@ -161,7 +163,7 @@ impl Parse for Module { let mut i = 0; while i < content.len() { match content[i] { - syn::Item::Mod(_) => { + syn::Item::Mod(..) => { let mut item_mod = match content.remove(i) { syn::Item::Mod(m) => m, _ => unreachable!(), @@ -212,7 +214,7 @@ impl Module { pub fn update_scope(&mut self, parent_scope: &ExportScope) { let keep = match (self.params.skip, parent_scope) { (true, ..) => false, - (.., ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(_)), + (.., ExportScope::PubOnly) => matches!(self.mod_all.vis, syn::Visibility::Public(..)), (.., ExportScope::Prefix(s)) => self.mod_all.ident.to_string().starts_with(s), (.., ExportScope::All) => true, }; diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index eda915f2..e3fd07af 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -99,7 +99,7 @@ pub fn generate_body( let fn_input_types: Vec<_> = function .arg_list() .map(|fn_arg| match fn_arg { - syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"), + syn::FnArg::Receiver(..) => panic!("internal error: receiver fn outside impl!?"), syn::FnArg::Typed(syn::PatType { ref ty, .. }) => { let arg_type = match flatten_type_groups(ty.as_ref()) { syn::Type::Reference(syn::TypeReference { @@ -150,7 +150,7 @@ pub fn generate_body( match function.params().special { FnSpecialAccess::None => (), - FnSpecialAccess::Index(_) | FnSpecialAccess::Property(_) => { + FnSpecialAccess::Index(..) | FnSpecialAccess::Property(..) => { let reg_name = fn_literal.value(); if reg_name.starts_with(FN_GET) || reg_name.starts_with(FN_SET) @@ -254,7 +254,7 @@ pub fn check_rename_collisions(fns: &[ExportedFn]) -> Result<(), syn::Error> { .arg_list() .fold(name.to_string(), |mut arg_str, fn_arg| { let type_string: String = match fn_arg { - syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"), + syn::FnArg::Receiver(..) => unimplemented!("receiver rhai_fns not implemented"), syn::FnArg::Typed(syn::PatType { ref ty, .. }) => print_type(ty), }; arg_str.push('.'); diff --git a/src/api/mod.rs b/src/api/mod.rs index b7d9b8f2..417ff39d 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -226,7 +226,7 @@ impl Engine { match Token::lookup_from_syntax(keyword.as_ref()) { // Standard identifiers, reserved keywords and custom keywords are OK - None | Some(Token::Reserved(_)) | Some(Token::Custom(_)) => (), + None | Some(Token::Reserved(..)) | Some(Token::Custom(..)) => (), // Active standard keywords cannot be made custom // Disabled keywords are OK Some(token) if token.is_standard_keyword() => { diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 02ea8545..0ccad835 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -449,7 +449,7 @@ impl AST { /// foo("!") /// "#)?; /// - /// // Merge 'ast2', picking only 'error()' but not 'foo(_)', into 'ast1' + /// // Merge 'ast2', picking only 'error()' but not 'foo(..)', into 'ast1' /// let ast = ast1.merge_filtered(&ast2, |_, _, script, name, params| /// script && name == "error" && params == 0); /// @@ -551,7 +551,7 @@ impl AST { /// foo("!") /// "#)?; /// - /// // Combine 'ast2', picking only 'error()' but not 'foo(_)', into 'ast1' + /// // Combine 'ast2', picking only 'error()' but not 'foo(..)', into 'ast1' /// ast1.combine_filtered(ast2, |_, _, script, name, params| /// script && name == "error" && params == 0); /// @@ -613,7 +613,7 @@ impl AST { /// fn bar() { print("hello"); } /// "#)?; /// - /// // Remove all functions except 'foo(_)' + /// // Remove all functions except 'foo(..)' /// ast.retain_functions(|_, _, name, params| name == "foo" && params == 1); /// # } /// # Ok(()) diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 75d23e9a..94e5b482 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -450,7 +450,7 @@ impl fmt::Debug for Expr { Self::FloatConstant(value, ..) => write!(f, "{:?}", value), Self::CharConstant(value, ..) => write!(f, "{:?}", value), Self::StringConstant(value, ..) => write!(f, "{:?}", value), - Self::Unit(_) => f.write_str("()"), + Self::Unit(..) => f.write_str("()"), Self::InterpolatedString(x, ..) => { f.write_str("InterpolatedString")?; @@ -535,7 +535,7 @@ impl Expr { Self::CharConstant(x, ..) => (*x).into(), Self::StringConstant(x, ..) => x.clone().into(), Self::BoolConstant(x, ..) => (*x).into(), - Self::Unit(_) => Dynamic::UNIT, + Self::Unit(..) => Dynamic::UNIT, #[cfg(not(feature = "no_index"))] Self::Array(x, ..) if self.is_constant() => { @@ -772,7 +772,7 @@ impl Expr { #[inline(always)] #[must_use] pub const fn is_unit(&self) -> bool { - matches!(self, Self::Unit(_)) + matches!(self, Self::Unit(..)) } /// Is the expression a constant? #[inline] @@ -787,7 +787,7 @@ impl Expr { | Self::IntegerConstant(..) | Self::CharConstant(..) | Self::StringConstant(..) - | Self::Unit(_) + | Self::Unit(..) | Self::Stack(..) => true, Self::InterpolatedString(x, ..) | Self::Array(x, ..) => x.iter().all(Self::is_constant), @@ -816,13 +816,13 @@ impl Expr { | Self::CharConstant(..) | Self::And(..) | Self::Or(..) - | Self::Unit(_) => false, + | Self::Unit(..) => false, Self::IntegerConstant(..) | Self::StringConstant(..) | Self::InterpolatedString(..) | Self::FnCall(..) - | Self::Stmt(_) + | Self::Stmt(..) | Self::Dot(..) | Self::Index(..) | Self::Array(..) diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index c33f5913..81f47d3d 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -404,7 +404,7 @@ impl Stmt { #[inline(always)] #[must_use] pub const fn is_noop(&self) -> bool { - matches!(self, Self::Noop(_)) + matches!(self, Self::Noop(..)) } /// Get the [position][Position] of this statement. #[must_use] @@ -432,7 +432,7 @@ impl Stmt { Self::Export(.., pos) => *pos, #[cfg(not(feature = "no_closure"))] - Self::Share(_) => Position::NONE, + Self::Share(..) => Position::NONE, } } /// Override the [position][Position] of this statement. @@ -462,7 +462,7 @@ impl Stmt { Self::Export(.., pos) => *pos = new_pos, #[cfg(not(feature = "no_closure"))] - Self::Share(_) => (), + Self::Share(..) => (), } self @@ -474,10 +474,10 @@ impl Stmt { Self::If(..) | Self::Switch(..) | Self::Block(..) - | Self::Expr(_) + | Self::Expr(..) | Self::FnCall(..) => true, - Self::Noop(_) | Self::While(..) | Self::Do(..) | Self::For(..) | Self::TryCatch(..) => { + Self::Noop(..) | Self::While(..) | Self::Do(..) | Self::For(..) | Self::TryCatch(..) => { false } @@ -487,7 +487,7 @@ impl Stmt { Self::Import(..) | Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] - Self::Share(_) => false, + Self::Share(..) => false, } } /// Is this statement self-terminated (i.e. no need for a semicolon terminator)? @@ -502,13 +502,13 @@ impl Stmt { | Self::TryCatch(..) => true, // A No-op requires a semicolon in order to know it is an empty statement! - Self::Noop(_) => false, + Self::Noop(..) => false, Self::Expr(Expr::Custom(x, ..)) if x.is_self_terminated() => true, Self::Var(..) | Self::Assignment(..) - | Self::Expr(_) + | Self::Expr(..) | Self::FnCall(..) | Self::Do(..) | Self::BreakLoop(..) @@ -518,7 +518,7 @@ impl Stmt { Self::Import(..) | Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] - Self::Share(_) => false, + Self::Share(..) => false, } } /// Is this statement _pure_? @@ -527,7 +527,7 @@ impl Stmt { #[must_use] pub fn is_pure(&self) -> bool { match self { - Self::Noop(_) => true, + Self::Noop(..) => true, Self::Expr(expr) => expr.is_pure(), Self::If(condition, x, ..) => { condition.is_pure() @@ -575,7 +575,7 @@ impl Stmt { Self::Export(..) => false, #[cfg(not(feature = "no_closure"))] - Self::Share(_) => false, + Self::Share(..) => false, } } /// Does this statement's behavior depend on its containing block? diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index 84c4a219..1185b720 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -724,7 +724,9 @@ impl Engine { match expr { #[cfg(not(feature = "no_object"))] - Expr::FnCall(x, ..) if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => { + Expr::FnCall(x, ..) + if _parent_chain_type == ChainType::Dotting && !x.is_qualified() => + { let crate::ast::FnCallExpr { args, constants, .. } = x.as_ref(); diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index 70aa50c2..d6f10ca0 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -465,16 +465,16 @@ impl Engine { // Skip transitive nodes match node { - ASTNode::Expr(Expr::Stmt(_)) | ASTNode::Stmt(Stmt::Expr(_)) => return Ok(None), + ASTNode::Expr(Expr::Stmt(..)) | ASTNode::Stmt(Stmt::Expr(..)) => return Ok(None), _ => (), } let stop = match global.debugger.status { DebuggerStatus::Next(false, false) => false, - DebuggerStatus::Next(true, false) => matches!(node, ASTNode::Stmt(_)), - DebuggerStatus::Next(false, true) => matches!(node, ASTNode::Expr(_)), + DebuggerStatus::Next(true, false) => matches!(node, ASTNode::Stmt(..)), + DebuggerStatus::Next(false, true) => matches!(node, ASTNode::Expr(..)), DebuggerStatus::Next(true, true) => true, - DebuggerStatus::FunctionExit(_) => false, + DebuggerStatus::FunctionExit(..) => false, }; let event = if stop { diff --git a/src/eval/expr.rs b/src/eval/expr.rs index a82504b1..f0e32227 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -324,7 +324,7 @@ impl Engine { Expr::StringConstant(x, ..) => Ok(x.clone().into()), Expr::CharConstant(x, ..) => Ok((*x).into()), Expr::BoolConstant(x, ..) => Ok((*x).into()), - Expr::Unit(_) => Ok(Dynamic::UNIT), + Expr::Unit(..) => Ok(Dynamic::UNIT), // `... ${...} ...` Expr::InterpolatedString(x, pos) => { diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index e57a9929..d81fc5e0 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -323,7 +323,7 @@ impl Engine { let result = match stmt { // No-op - Stmt::Noop(_) => Ok(Dynamic::UNIT), + Stmt::Noop(..) => Ok(Dynamic::UNIT), // Expression as statement Stmt::Expr(expr) => self @@ -483,7 +483,7 @@ impl Engine { } // Loop - Stmt::While(Expr::Unit(_), body, ..) => loop { + Stmt::While(Expr::Unit(..), body, ..) => loop { if !body.is_empty() { match self .eval_stmt_block(scope, global, state, lib, this_ptr, body, true, level) diff --git a/src/eval/target.rs b/src/eval/target.rs index f31647f9..eb046be2 100644 --- a/src/eval/target.rs +++ b/src/eval/target.rs @@ -144,10 +144,10 @@ impl<'a> Target<'a> { #[must_use] pub const fn is_ref(&self) -> bool { match self { - Self::RefMut(_) => true, + Self::RefMut(..) => true, #[cfg(not(feature = "no_closure"))] Self::SharedValue { .. } => true, - Self::TempValue(_) => false, + Self::TempValue(..) => false, #[cfg(not(feature = "no_index"))] Self::Bit { .. } | Self::BitField { .. } @@ -160,10 +160,10 @@ impl<'a> Target<'a> { #[must_use] pub const fn is_temp_value(&self) -> bool { match self { - Self::RefMut(_) => false, + Self::RefMut(..) => false, #[cfg(not(feature = "no_closure"))] Self::SharedValue { .. } => false, - Self::TempValue(_) => true, + Self::TempValue(..) => true, #[cfg(not(feature = "no_index"))] Self::Bit { .. } | Self::BitField { .. } @@ -275,7 +275,7 @@ impl<'a> Target<'a> { #[inline] pub fn propagate_changed_value(&mut self) -> RhaiResultOf<()> { match self { - Self::RefMut(_) | Self::TempValue(_) => (), + Self::RefMut(..) | Self::TempValue(..) => (), #[cfg(not(feature = "no_closure"))] Self::SharedValue { .. } => (), #[cfg(not(feature = "no_index"))] diff --git a/src/func/call.rs b/src/func/call.rs index bb19eda7..f4c6a07f 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -972,7 +972,7 @@ impl Engine { // Do not match function exit for arguments #[cfg(feature = "debugging")] let reset_debugger = global.debugger.clear_status_if(|status| { - matches!(status, crate::eval::DebuggerStatus::FunctionExit(_)) + matches!(status, crate::eval::DebuggerStatus::FunctionExit(..)) }); let result = self.eval_expr(scope, global, state, lib, this_ptr, arg_expr, level); diff --git a/src/func/callable_function.rs b/src/func/callable_function.rs index 3febb448..86e4d4f3 100644 --- a/src/func/callable_function.rs +++ b/src/func/callable_function.rs @@ -30,10 +30,10 @@ pub enum CallableFunction { impl fmt::Debug for CallableFunction { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::Pure(_) => write!(f, "NativePureFunction"), - Self::Method(_) => write!(f, "NativeMethod"), - Self::Iterator(_) => write!(f, "NativeIterator"), - Self::Plugin(_) => write!(f, "PluginFunction"), + Self::Pure(..) => write!(f, "NativePureFunction"), + Self::Method(..) => write!(f, "NativeMethod"), + Self::Iterator(..) => write!(f, "NativeIterator"), + Self::Plugin(..) => write!(f, "PluginFunction"), #[cfg(not(feature = "no_function"))] Self::Script(fn_def) => fmt::Debug::fmt(fn_def, f), @@ -44,10 +44,10 @@ impl fmt::Debug for CallableFunction { impl fmt::Display for CallableFunction { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::Pure(_) => write!(f, "NativePureFunction"), - Self::Method(_) => write!(f, "NativeMethod"), - Self::Iterator(_) => write!(f, "NativeIterator"), - Self::Plugin(_) => write!(f, "PluginFunction"), + Self::Pure(..) => write!(f, "NativePureFunction"), + Self::Method(..) => write!(f, "NativeMethod"), + Self::Iterator(..) => write!(f, "NativeIterator"), + Self::Plugin(..) => write!(f, "PluginFunction"), #[cfg(not(feature = "no_function"))] Self::Script(s) => fmt::Display::fmt(s, f), @@ -61,13 +61,13 @@ impl CallableFunction { #[must_use] pub fn is_pure(&self) -> bool { match self { - Self::Pure(_) => true, - Self::Method(_) | Self::Iterator(_) => false, + Self::Pure(..) => true, + Self::Method(..) | Self::Iterator(..) => false, Self::Plugin(p) => !p.is_method_call(), #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, + Self::Script(..) => false, } } /// Is this a native Rust method function? @@ -75,13 +75,13 @@ impl CallableFunction { #[must_use] pub fn is_method(&self) -> bool { match self { - Self::Method(_) => true, - Self::Pure(_) | Self::Iterator(_) => false, + Self::Method(..) => true, + Self::Pure(..) | Self::Iterator(..) => false, Self::Plugin(p) => p.is_method_call(), #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, + Self::Script(..) => false, } } /// Is this an iterator function? @@ -89,11 +89,11 @@ impl CallableFunction { #[must_use] pub const fn is_iter(&self) -> bool { match self { - Self::Iterator(_) => true, - Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => false, + Self::Iterator(..) => true, + Self::Pure(..) | Self::Method(..) | Self::Plugin(..) => false, #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, + Self::Script(..) => false, } } /// Is this a script-defined function? @@ -105,8 +105,8 @@ impl CallableFunction { #[cfg(not(feature = "no_function"))] match self { - Self::Script(_) => true, - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => false, + Self::Script(..) => true, + Self::Pure(..) | Self::Method(..) | Self::Iterator(..) | Self::Plugin(..) => false, } } /// Is this a plugin function? @@ -114,11 +114,11 @@ impl CallableFunction { #[must_use] pub const fn is_plugin_fn(&self) -> bool { match self { - Self::Plugin(_) => true, - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => false, + Self::Plugin(..) => true, + Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => false, #[cfg(not(feature = "no_function"))] - Self::Script(_) => false, + Self::Script(..) => false, } } /// Is this a native Rust function? @@ -130,10 +130,10 @@ impl CallableFunction { #[cfg(not(feature = "no_function"))] match self { - Self::Pure(_) | Self::Method(_) => true, - Self::Plugin(_) => true, - Self::Iterator(_) => true, - Self::Script(_) => false, + Self::Pure(..) | Self::Method(..) => true, + Self::Plugin(..) => true, + Self::Iterator(..) => true, + Self::Script(..) => false, } } /// Get the access mode. @@ -145,8 +145,8 @@ impl CallableFunction { #[cfg(not(feature = "no_function"))] match self { - Self::Plugin(_) => FnAccess::Public, - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => FnAccess::Public, + Self::Plugin(..) => FnAccess::Public, + Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => FnAccess::Public, Self::Script(f) => f.access, } } @@ -156,10 +156,10 @@ impl CallableFunction { pub fn get_native_fn(&self) -> Option<&Shared> { match self { Self::Pure(f) | Self::Method(f) => Some(f), - Self::Iterator(_) | Self::Plugin(_) => None, + Self::Iterator(..) | Self::Plugin(..) => None, #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, + Self::Script(..) => None, } } /// Get a shared reference to a script-defined function definition. @@ -170,7 +170,7 @@ impl CallableFunction { #[must_use] pub const fn get_script_fn_def(&self) -> Option<&Shared> { match self { - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) | Self::Plugin(_) => None, + Self::Pure(..) | Self::Method(..) | Self::Iterator(..) | Self::Plugin(..) => None, Self::Script(f) => Some(f), } } @@ -180,10 +180,10 @@ impl CallableFunction { pub fn get_iter_fn(&self) -> Option<&IteratorFn> { match self { Self::Iterator(f) => Some(f.as_ref()), - Self::Pure(_) | Self::Method(_) | Self::Plugin(_) => None, + Self::Pure(..) | Self::Method(..) | Self::Plugin(..) => None, #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, + Self::Script(..) => None, } } /// Get a shared reference to a plugin function. @@ -192,10 +192,10 @@ impl CallableFunction { pub fn get_plugin_fn(&self) -> Option<&Shared> { match self { Self::Plugin(f) => Some(f), - Self::Pure(_) | Self::Method(_) | Self::Iterator(_) => None, + Self::Pure(..) | Self::Method(..) | Self::Iterator(..) => None, #[cfg(not(feature = "no_function"))] - Self::Script(_) => None, + Self::Script(..) => None, } } /// Create a new [`CallableFunction::Pure`]. diff --git a/src/optimizer.rs b/src/optimizer.rs index f53c51ac..e8ddf4f8 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -349,7 +349,7 @@ fn optimize_stmt_block( .map_or_else(|| Stmt::Noop(pos), |e| Stmt::Expr(mem::take(e))); } // { ...; stmt; noop } -> done - [.., ref second_last_stmt, Stmt::Noop(_)] + [.., ref second_last_stmt, Stmt::Noop(..)] if second_last_stmt.returns_value() => { break @@ -636,7 +636,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Some(mut condition) = mem::take(&mut block.condition) { optimize_expr(&mut condition, state, false); match condition { - Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(), + Expr::Unit(..) | Expr::BoolConstant(true, ..) => state.set_dirty(), _ => block.condition = Some(condition), } } @@ -665,7 +665,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b if let Some(mut condition) = mem::take(&mut block.condition) { optimize_expr(&mut condition, state, false); match condition { - Expr::Unit(_) | Expr::BoolConstant(true, ..) => state.set_dirty(), + Expr::Unit(..) | Expr::BoolConstant(true, ..) => state.set_dirty(), _ => block.condition = Some(condition), } } @@ -941,8 +941,8 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { while n < x.len() - 1 { match (mem::take(&mut x[n]), mem::take(&mut x[n+1])) { (Expr::StringConstant(mut s1, pos), Expr::StringConstant(s2, ..)) => { s1 += s2; x[n] = Expr::StringConstant(s1, pos); x.remove(n+1); state.set_dirty(); } - (expr1, Expr::Unit(_)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } - (Expr::Unit(_), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); } + (expr1, Expr::Unit(..)) => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } + (Expr::Unit(..), expr2) => { x[n+1] = expr2; x.remove(n); state.set_dirty(); } (expr1, Expr::StringConstant(s, ..)) if s.is_empty() => { x[n] = expr1; x.remove(n+1); state.set_dirty(); } (Expr::StringConstant(s, ..), expr2) if s.is_empty()=> { x[n+1] = expr2; x.remove(n); state.set_dirty(); } (expr1, expr2) => { x[n] = expr1; x[n+1] = expr2; n += 1; } diff --git a/src/parser.rs b/src/parser.rs index df637d7a..e9e382e4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -291,7 +291,7 @@ impl Expr { /// Raise an error if the expression can never yield a boolean value. fn ensure_bool_expr(self) -> ParseResult { let type_name = match self { - Expr::Unit(_) => "()", + Expr::Unit(..) => "()", Expr::DynamicConstant(ref v, ..) if !v.is::() => v.type_name(), Expr::IntegerConstant(..) => "a number", #[cfg(not(feature = "no_float"))] @@ -312,7 +312,7 @@ impl Expr { /// Raise an error if the expression can never yield an iterable value. fn ensure_iterable(self) -> ParseResult { let type_name = match self { - Expr::Unit(_) => "()", + Expr::Unit(..) => "()", Expr::BoolConstant(..) => "a boolean", Expr::IntegerConstant(..) => "a number", #[cfg(not(feature = "no_float"))] @@ -661,7 +661,7 @@ fn parse_index_chain( | Expr::And(..) | Expr::Or(..) | Expr::BoolConstant(..) - | Expr::Unit(_) => { + | Expr::Unit(..) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), ) @@ -694,7 +694,7 @@ fn parse_index_chain( | Expr::And(..) | Expr::Or(..) | Expr::BoolConstant(..) - | Expr::Unit(_) => { + | Expr::Unit(..) => { return Err(PERR::MalformedIndexExpr( "Only arrays, object maps and strings can be indexed".into(), ) @@ -720,7 +720,7 @@ fn parse_index_chain( .into_err(x.start_position())) } // lhs[()] - x @ Expr::Unit(_) => { + x @ Expr::Unit(..) => { return Err(PERR::MalformedIndexExpr( "Array access expects integer index, not ()".into(), ) @@ -897,7 +897,9 @@ fn parse_map_literal( } (s, pos) } - (Token::InterpolatedString(_), pos) => return Err(PERR::PropertyExpected.into_err(pos)), + (Token::InterpolatedString(..), pos) => { + return Err(PERR::PropertyExpected.into_err(pos)) + } (Token::Reserved(s), pos) if is_valid_identifier(s.chars()) => { return Err(PERR::Reserved(s.to_string()).into_err(pos)); } @@ -951,7 +953,7 @@ fn parse_map_literal( eat_token(input, Token::Comma); } (Token::RightBrace, ..) => (), - (Token::Identifier(_), pos) => { + (Token::Identifier(..), pos) => { return Err(PERR::MissingToken( Token::Comma.into(), "to separate the items of this object map literal".into(), @@ -1147,7 +1149,7 @@ fn parse_switch( ) .into_err(*pos)) } - (..) => (), + _ => (), } } @@ -1183,9 +1185,9 @@ fn parse_primary( let root_expr = match token { Token::EOF => return Err(PERR::UnexpectedEOF.into_err(settings.pos)), - Token::IntegerConstant(_) - | Token::CharConstant(_) - | Token::StringConstant(_) + Token::IntegerConstant(..) + | Token::CharConstant(..) + | Token::StringConstant(..) | Token::True | Token::False => match input.next().expect(NEVER_ENDS).0 { Token::IntegerConstant(x) => Expr::IntegerConstant(x, settings.pos), @@ -1284,7 +1286,7 @@ fn parse_primary( } // Interpolated string - Token::InterpolatedString(_) => { + Token::InterpolatedString(..) => { let mut segments = StaticVec::::new(); match input.next().expect(NEVER_ENDS) { @@ -1352,7 +1354,7 @@ fn parse_primary( } // Identifier - Token::Identifier(_) => { + Token::Identifier(..) => { #[cfg(not(feature = "no_module"))] let none = None; #[cfg(feature = "no_module")] @@ -1416,7 +1418,7 @@ fn parse_primary( } // Reserved keyword or symbol - Token::Reserved(_) => { + Token::Reserved(..) => { #[cfg(not(feature = "no_module"))] let none = None; #[cfg(feature = "no_module")] @@ -1450,7 +1452,7 @@ fn parse_primary( } } - Token::LexError(_) => match input.next().expect(NEVER_ENDS) { + Token::LexError(..) => match input.next().expect(NEVER_ENDS) { (Token::LexError(err), ..) => return Err(err.into_err(settings.pos)), token => unreachable!("Token::LexError expected but gets {:?}", token), }, @@ -1575,7 +1577,7 @@ fn parse_postfix( (expr, Token::Period) => { // Expression after dot must start with an identifier match input.peek().expect(NEVER_ENDS) { - (Token::Identifier(_), ..) => { + (Token::Identifier(..), ..) => { #[cfg(not(feature = "no_closure"))] { // Prevents capturing of the object properties as vars: xxx. @@ -2792,7 +2794,7 @@ fn parse_block( eat_token(input, Token::SemiColon); } // { ... { stmt } ??? - (..) if !need_semicolon => (), + _ if !need_semicolon => (), // { ... stmt (Token::LexError(err), err_pos) => return Err(err.clone().into_err(*err_pos)), // { ... stmt ??? @@ -2874,7 +2876,7 @@ fn parse_stmt( match input.peek().expect(NEVER_ENDS) { (Token::Fn, ..) | (Token::Private, ..) => break, - (Token::Comment(_), ..) => (), + (Token::Comment(..), ..) => (), _ => return Err(PERR::WrongDocComment.into_err(comments_pos)), } } @@ -3027,7 +3029,7 @@ fn parse_stmt( // `return;` or `throw;` (Token::SemiColon, ..) => Ok(Stmt::Return(return_type, None, token_pos)), // `return` or `throw` with expression - (..) => { + _ => { let expr = parse_expr(input, state, lib, settings.level_up())?; Ok(Stmt::Return(return_type, Some(expr), token_pos)) } @@ -3491,7 +3493,7 @@ impl Engine { // stmt ; (Token::SemiColon, ..) if !need_semicolon => (), // { stmt } ??? - (..) if !need_semicolon => (), + _ if !need_semicolon => (), // stmt (Token::LexError(err), pos) => return Err(err.clone().into_err(*pos)), // stmt ??? diff --git a/src/tokenizer.rs b/src/tokenizer.rs index e1b2081b..ecc887aa 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -603,8 +603,8 @@ impl Token { FloatConstant(f) => f.to_string().into(), #[cfg(feature = "decimal")] DecimalConstant(d) => d.to_string().into(), - StringConstant(_) => "string".into(), - InterpolatedString(_) => "string".into(), + StringConstant(..) => "string".into(), + InterpolatedString(..) => "string".into(), CharConstant(c) => c.to_string().into(), Identifier(s) => s.to_string().into(), Reserved(s) => s.to_string().into(), @@ -825,7 +825,7 @@ impl Token { use Token::*; match self { - LexError(_) | + LexError(..) | SemiColon | // ; - is unary Colon | // #{ foo: - is unary Comma | // ( ... , -expr ) - is unary @@ -970,7 +970,7 @@ impl Token { #[inline(always)] #[must_use] pub const fn is_reserved(&self) -> bool { - matches!(self, Self::Reserved(_)) + matches!(self, Self::Reserved(..)) } /// Convert a token into a function name, if possible. @@ -987,7 +987,7 @@ impl Token { #[inline(always)] #[must_use] pub const fn is_custom(&self) -> bool { - matches!(self, Self::Custom(_)) + matches!(self, Self::Custom(..)) } } @@ -2197,7 +2197,7 @@ impl<'a> Iterator for TokenIterator<'a> { // a verbatim string or a string with continuation encounters {EOF}. // This is necessary to handle such cases for line-by-line parsing, but for an entire // script it is a syntax error. - Some((Token::StringConstant(_), pos)) if self.state.is_within_text_terminated_by.is_some() => { + Some((Token::StringConstant(..), pos)) if self.state.is_within_text_terminated_by.is_some() => { self.state.is_within_text_terminated_by = None; return Some((Token::LexError(LERR::UnterminatedString), pos)); } diff --git a/src/types/error.rs b/src/types/error.rs index 93044334..e79d7ec8 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -153,11 +153,11 @@ impl fmt::Display for EvalAltResult { s => f.write_str(s), }?, Self::ErrorIndexingType(s, ..) => write!(f, "Indexer not registered: {}", s)?, - Self::ErrorUnboundThis(_) => f.write_str("'this' is not bound")?, - Self::ErrorFor(_) => f.write_str("For loop expects a type that is iterable")?, - Self::ErrorTooManyOperations(_) => f.write_str("Too many operations")?, - Self::ErrorTooManyModules(_) => f.write_str("Too many modules imported")?, - Self::ErrorStackOverflow(_) => f.write_str("Stack overflow")?, + Self::ErrorUnboundThis(..) => f.write_str("'this' is not bound")?, + Self::ErrorFor(..) => f.write_str("For loop expects a type that is iterable")?, + Self::ErrorTooManyOperations(..) => f.write_str("Too many operations")?, + Self::ErrorTooManyModules(..) => f.write_str("Too many modules imported")?, + Self::ErrorStackOverflow(..) => f.write_str("Stack overflow")?, Self::ErrorTerminated(..) => f.write_str("Script terminated")?, Self::ErrorRuntime(d, ..) if d.is::<()>() => f.write_str("Runtime error")?, @@ -270,13 +270,13 @@ impl EvalAltResult { Self::ErrorFunctionNotFound(..) | Self::ErrorInFunctionCall(..) | Self::ErrorInModule(..) - | Self::ErrorUnboundThis(_) + | Self::ErrorUnboundThis(..) | Self::ErrorMismatchDataType(..) | Self::ErrorArrayBounds(..) | Self::ErrorStringBounds(..) | Self::ErrorBitFieldBounds(..) | Self::ErrorIndexingType(..) - | Self::ErrorFor(_) + | Self::ErrorFor(..) | Self::ErrorVariableExists(..) | Self::ErrorVariableNotFound(..) | Self::ErrorModuleNotFound(..) @@ -293,9 +293,9 @@ impl EvalAltResult { // Therefore, this error should not be catchable. Self::ErrorCustomSyntax(..) => false, - Self::ErrorTooManyOperations(_) - | Self::ErrorTooManyModules(_) - | Self::ErrorStackOverflow(_) + Self::ErrorTooManyOperations(..) + | Self::ErrorTooManyModules(..) + | Self::ErrorStackOverflow(..) | Self::ErrorDataTooLarge(..) | Self::ErrorTerminated(..) => false, @@ -310,9 +310,9 @@ impl EvalAltResult { Self::ErrorParsing(..) => true, Self::ErrorCustomSyntax(..) - | Self::ErrorTooManyOperations(_) - | Self::ErrorTooManyModules(_) - | Self::ErrorStackOverflow(_) + | Self::ErrorTooManyOperations(..) + | Self::ErrorTooManyModules(..) + | Self::ErrorStackOverflow(..) | Self::ErrorDataTooLarge(..) => true, Self::ErrorTerminated(..) => true, @@ -337,12 +337,12 @@ impl EvalAltResult { Self::ErrorSystem(..) | Self::ErrorParsing(..) - | Self::ErrorUnboundThis(_) - | Self::ErrorFor(_) + | Self::ErrorUnboundThis(..) + | Self::ErrorFor(..) | Self::ErrorArithmetic(..) - | Self::ErrorTooManyOperations(_) - | Self::ErrorTooManyModules(_) - | Self::ErrorStackOverflow(_) + | Self::ErrorTooManyOperations(..) + | Self::ErrorTooManyModules(..) + | Self::ErrorStackOverflow(..) | Self::ErrorRuntime(..) => (), Self::ErrorFunctionNotFound(f, ..) => { diff --git a/tests/closures.rs b/tests/closures.rs index 8a323f97..36ae9e33 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -48,7 +48,7 @@ fn test_closures() -> Result<(), Box> { .compile_expression("let f = |x| {};") .expect_err("should error") .0, - ParseErrorType::BadInput(_) + ParseErrorType::BadInput(..) )); assert_eq!( diff --git a/tests/fn_ptr.rs b/tests/fn_ptr.rs index 41ad29af..0944ea58 100644 --- a/tests/fn_ptr.rs +++ b/tests/fn_ptr.rs @@ -74,7 +74,7 @@ fn test_fn_ptr() -> Result<(), Box> { ) .expect_err("should error"), EvalAltResult::ErrorInFunctionCall(fn_name, _, err, ..) - if fn_name == "foo" && matches!(*err, EvalAltResult::ErrorUnboundThis(_)) + if fn_name == "foo" && matches!(*err, EvalAltResult::ErrorUnboundThis(..)) )); Ok(()) diff --git a/tests/internal_fn.rs b/tests/internal_fn.rs index 62bf001d..72808e96 100644 --- a/tests/internal_fn.rs +++ b/tests/internal_fn.rs @@ -249,7 +249,7 @@ fn test_internal_fn_bang() -> Result<(), Box> { ) .expect_err("should error") .0, - ParseErrorType::MalformedCapture(_) + ParseErrorType::MalformedCapture(..) )); Ok(()) diff --git a/tests/modules.rs b/tests/modules.rs index 63409844..25e17117 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -214,7 +214,7 @@ fn test_module_resolver() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorTooManyModules(_) + EvalAltResult::ErrorTooManyModules(..) )); #[cfg(not(feature = "no_function"))] diff --git a/tests/operations.rs b/tests/operations.rs index b5b73ebd..d6b7b69f 100644 --- a/tests/operations.rs +++ b/tests/operations.rs @@ -19,7 +19,7 @@ fn test_max_operations() -> Result<(), Box> { assert!(matches!( *engine.run("for x in 0..500 {}").expect_err("should error"), - EvalAltResult::ErrorTooManyOperations(_) + EvalAltResult::ErrorTooManyOperations(..) )); engine.set_max_operations(0); @@ -44,7 +44,7 @@ fn test_max_operations_literal() -> Result<(), Box> { *engine .run("[1, 2, 3, 4, 5, 6, 7, 8, 9]") .expect_err("should error"), - EvalAltResult::ErrorTooManyOperations(_) + EvalAltResult::ErrorTooManyOperations(..) )); #[cfg(not(feature = "no_object"))] @@ -55,7 +55,7 @@ fn test_max_operations_literal() -> Result<(), Box> { *engine .run("#{a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9}") .expect_err("should error"), - EvalAltResult::ErrorTooManyOperations(_) + EvalAltResult::ErrorTooManyOperations(..) )); Ok(()) @@ -111,7 +111,7 @@ fn test_max_operations_functions() -> Result<(), Box> { "#, ) .expect_err("should error"), - EvalAltResult::ErrorTooManyOperations(_) + EvalAltResult::ErrorTooManyOperations(..) )); Ok(()) @@ -138,7 +138,7 @@ fn test_max_operations_eval() -> Result<(), Box> { "# ) .expect_err("should error"), - EvalAltResult::ErrorInFunctionCall(.., err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(_)) + EvalAltResult::ErrorInFunctionCall(.., err, _) if matches!(*err, EvalAltResult::ErrorTooManyOperations(..)) )); Ok(()) diff --git a/tests/stack.rs b/tests/stack.rs index c2a8d21d..c10b4133 100644 --- a/tests/stack.rs +++ b/tests/stack.rs @@ -29,7 +29,7 @@ fn test_stack_overflow_fn_calls() -> Result<(), Box> { max + 1 )) .expect_err("should error"), - EvalAltResult::ErrorStackOverflow(_) + EvalAltResult::ErrorStackOverflow(..) )); Ok(()) From 83b213b0866735f60f8da79902d27e960c2aa9bb Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 19:02:40 +0800 Subject: [PATCH 10/12] Unwrap error when caught. --- CHANGELOG.md | 2 ++ src/bin/rhai-dbg.rs | 13 +++++++++++-- src/eval/stmt.rs | 4 ++-- src/types/error.rs | 10 ++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 571ec17e..ba6d5d2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Bug fixes * Off-by-one error in character positions after a comment line is now fixed. * Globally-defined constants are now encapsulated correctly inside a loaded module and no longer spill across call boundaries. * Type names display is fixed. +* Exceptions thrown inside function calls now unwrap correctly when `catch`-ed. Script-breaking changes ----------------------- @@ -40,6 +41,7 @@ Enhancements * `AST` position display is improved: * `Expr::start_position` is added to give the beginning of the expression (not the operator's position). * `StmtBlock` and `Stmt::Block` now keep the position of the closing `}` as well. +* `EvalAltResult::unwrap_inner` is added to access the base error inside multiple layers of wrappings (e.g. `EvalAltResult::ErrorInFunction`). REPL tool changes ----------------- diff --git a/src/bin/rhai-dbg.rs b/src/bin/rhai-dbg.rs index d5b9de06..4b289985 100644 --- a/src/bin/rhai-dbg.rs +++ b/src/bin/rhai-dbg.rs @@ -1,5 +1,5 @@ use rhai::debugger::{BreakPoint, DebuggerCommand, DebuggerEvent}; -use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString, Position, Scope}; +use rhai::{Dynamic, Engine, EvalAltResult, ImmutableString, Position, Scope, INT}; use std::{ env, @@ -553,7 +553,16 @@ fn main() { ["throw"] => { break Err(EvalAltResult::ErrorRuntime(Dynamic::UNIT, pos).into()) } - ["throw", _msg, ..] => { + ["throw", num] if num.trim().parse::().is_ok() => { + let value = num.trim().parse::().unwrap().into(); + break Err(EvalAltResult::ErrorRuntime(value, pos).into()); + } + #[cfg(not(feature = "no_float"))] + ["throw", num] if num.trim().parse::().is_ok() => { + let value = num.trim().parse::().unwrap().into(); + break Err(EvalAltResult::ErrorRuntime(value, pos).into()); + } + ["throw", ..] => { let msg = input.trim().splitn(2, ' ').skip(1).next().unwrap_or(""); break Err(EvalAltResult::ErrorRuntime(msg.trim().into(), pos).into()); } diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index d81fc5e0..a06bb742 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -715,8 +715,8 @@ impl Engine { Err(err) if err.is_pseudo_error() => Err(err), Err(err) if !err.is_catchable() => Err(err), Err(mut err) => { - let err_value = match *err { - ERR::ErrorRuntime(ref x, ..) => x.clone(), + let err_value = match err.unwrap_inner() { + ERR::ErrorRuntime(x, ..) => x.clone(), #[cfg(feature = "no_object")] _ => { diff --git a/src/types/error.rs b/src/types/error.rs index e79d7ec8..32d3195b 100644 --- a/src/types/error.rs +++ b/src/types/error.rs @@ -403,6 +403,16 @@ impl EvalAltResult { } }; } + /// Unwrap this error and get the very base error. + #[must_use] + pub fn unwrap_inner(&self) -> &Self { + match self { + Self::ErrorInFunctionCall(.., err, _) | Self::ErrorInModule(.., err, _) => { + err.unwrap_inner() + } + _ => self, + } + } /// Get the [position][Position] of this error. #[must_use] pub const fn position(&self) -> Position { From 8cf6f424a508af84e29a42384f3008ac8929f846 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 21:28:15 +0800 Subject: [PATCH 11/12] Use turbofish notation. --- src/ast/stmt.rs | 8 +++++--- src/eval/chaining.rs | 12 +++++++----- src/func/call.rs | 21 +++++++++------------ src/parser.rs | 11 ++++++----- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 81f47d3d..6c980e1d 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -477,9 +477,11 @@ impl Stmt { | Self::Expr(..) | Self::FnCall(..) => true, - Self::Noop(..) | Self::While(..) | Self::Do(..) | Self::For(..) | Self::TryCatch(..) => { - false - } + Self::Noop(..) + | Self::While(..) + | Self::Do(..) + | Self::For(..) + | Self::TryCatch(..) => false, Self::Var(..) | Self::Assignment(..) | Self::BreakLoop(..) | Self::Return(..) => false, diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index 1185b720..898ab201 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -4,7 +4,9 @@ use super::{EvalState, GlobalRuntimeState, Target}; use crate::ast::{Expr, OpAssignment}; use crate::types::dynamic::Union; -use crate::{Dynamic, Engine, Module, Position, RhaiResult, RhaiResultOf, Scope, StaticVec, ERR}; +use crate::{ + Dynamic, Engine, Module, Position, RhaiError, RhaiResult, RhaiResultOf, Scope, StaticVec, ERR, +}; use std::hash::Hash; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -733,7 +735,7 @@ impl Engine { let (values, pos) = args.iter().try_fold( (crate::FnArgsVec::with_capacity(args.len()), Position::NONE), - |(mut values, mut pos), expr| -> RhaiResultOf<_> { + |(mut values, mut pos), expr| { let (value, arg_pos) = self.get_arg_value( scope, global, state, lib, this_ptr, expr, constants, level, )?; @@ -741,7 +743,7 @@ impl Engine { pos = arg_pos; } values.push(value.flatten()); - Ok((values, pos)) + Ok::<_, RhaiError>((values, pos)) }, )?; @@ -779,7 +781,7 @@ impl Engine { let (values, pos) = args.iter().try_fold( (crate::FnArgsVec::with_capacity(args.len()), Position::NONE), - |(mut values, mut pos), expr| -> RhaiResultOf<_> { + |(mut values, mut pos), expr| { let (value, arg_pos) = self.get_arg_value( scope, global, state, lib, this_ptr, expr, constants, level, )?; @@ -787,7 +789,7 @@ impl Engine { pos = arg_pos } values.push(value.flatten()); - Ok((values, pos)) + Ok::<_, RhaiError>((values, pos)) }, )?; super::ChainArgument::from_fn_call_args(values, pos) diff --git a/src/func/call.rs b/src/func/call.rs index f4c6a07f..5a13b03f 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -12,8 +12,8 @@ use crate::engine::{ use crate::eval::{EvalState, GlobalRuntimeState}; use crate::{ calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnArgsVec, FnPtr, - Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiResult, RhaiResultOf, - Scope, ERR, + Identifier, ImmutableString, Module, OptimizationLevel, Position, RhaiError, RhaiResult, + RhaiResultOf, Scope, ERR, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -1079,16 +1079,13 @@ impl Engine { let (name, fn_curry) = arg_value.cast::().take_data(); // Append the new curried arguments to the existing list. - let fn_curry = - a_expr - .iter() - .try_fold(fn_curry, |mut curried, expr| -> RhaiResultOf<_> { - let (value, ..) = self.get_arg_value( - scope, global, state, lib, this_ptr, expr, constants, level, - )?; - curried.push(value); - Ok(curried) - })?; + let fn_curry = a_expr.iter().try_fold(fn_curry, |mut curried, expr| { + let (value, ..) = self.get_arg_value( + scope, global, state, lib, this_ptr, expr, constants, level, + )?; + curried.push(value); + Ok::<_, RhaiError>(curried) + })?; return Ok(FnPtr::new_unchecked(name, fn_curry).into()); } diff --git a/src/parser.rs b/src/parser.rs index e9e382e4..8f5a28ca 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1264,8 +1264,10 @@ fn parse_primary( let (expr, func) = parse_anon_fn(input, &mut new_state, lib, new_settings)?; #[cfg(not(feature = "no_closure"))] - new_state.external_vars.iter().try_for_each( - |crate::ast::Ident { name, pos }| -> ParseResult<_> { + new_state + .external_vars + .iter() + .try_for_each(|crate::ast::Ident { name, pos }| { let index = state.access_var(name, *pos); if settings.strict_var && !settings.is_closure && index.is_none() { @@ -1274,10 +1276,9 @@ fn parse_primary( // Under Strict Variables mode, this is not allowed. Err(PERR::VariableUndefined(name.to_string()).into_err(*pos)) } else { - Ok(()) + Ok::<_, ParseError>(()) } - }, - )?; + })?; let hash_script = calc_fn_hash(&func.name, func.params.len()); lib.insert(hash_script, func.into()); From 5e7db6e1051bf2c75d78258b33704c57d4236a53 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 8 Feb 2022 22:16:12 +0800 Subject: [PATCH 12/12] Use new version of rustyline. --- CHANGELOG.md | 7 ++++--- Cargo.toml | 4 +++- src/bin/rhai-repl.rs | 21 ++++++--------------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba6d5d2d..4942004e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,15 +55,16 @@ The REPL bin tool, `rhai-rpl`, has been enhanced. ### Line editor -* `rhai-repl` now uses [`rustyline`](https://crates.io/crates/rustyline) as a line editor with history. -* Shift-Enter can now be used to enter multiple lines without having to attach the `\` continuation character the end of each line. +* `rhai-repl` now uses a modified version of [`rustyline`](https://crates.io/crates/rustyline) as a line editor with history. +* Ctrl-Enter can now be used to enter multiple lines without having to attach the `\` continuation character the end of each line. +* Bracketed paste is supported, even on Windows (version 10 or above), so pasting code directly into `rhai-repl` is made much more convenient. ### New commands * `strict` to turn on/off _Strict Variables Mode_. * `optimize` to turn on/off script optimization. * `history` to print lines history. -* `!!`, `!`_num_ and `!`_text_ to recall a history line. +* `!!`, `!`_num_, `!`_text_ and `!?`_text_ to recall a history line. * `keys` to print all key bindings. diff --git a/Cargo.toml b/Cargo.toml index 19fcad41..4fb2e519 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,9 @@ serde = { version = "1.0", default-features = false, features = ["derive", "allo serde_json = { version = "1.0", default-features = false, features = ["alloc"], optional = true } unicode-xid = { version = "0.2", default-features = false, optional = true } rust_decimal = { version = "1.16", default-features = false, features = ["maths"], optional = true } -rustyline = { version = "9", optional = true } +# notice that a custom modified version of `rustyline` is used which supports bracketed paste on Windows +# this can be moved to the official version when bracketed paste is added +rustyline = { version = "9", optional = true, git = "https://github.com/schungx/rustyline", branch = "bracketed_paste" } [dev-dependencies] serde_bytes = "0.11" diff --git a/src/bin/rhai-repl.rs b/src/bin/rhai-repl.rs index 8328dbe8..5d574860 100644 --- a/src/bin/rhai-repl.rs +++ b/src/bin/rhai-repl.rs @@ -62,8 +62,8 @@ fn print_help() { println!("ast => print the last AST (optimized)"); println!("astu => print the last raw, un-optimized AST"); println!(); - println!("press Shift-Enter to continue to the next line,"); - println!(r"or end a line with '\' (e.g. when pasting code)."); + println!("press Ctrl-Enter or end a line with `\\`"); + println!("to continue to the next line."); println!(); } @@ -204,6 +204,7 @@ fn load_script_files(engine: &mut Engine) { // Setup the Rustyline editor. fn setup_editor() -> Editor<()> { + //env_logger::init(); let config = Builder::new() .tab_stop(4) .indent_size(4) @@ -225,23 +226,13 @@ fn setup_editor() -> Editor<()> { Event::KeySeq(smallvec![KeyEvent::ctrl('z')]), EventHandler::Simple(Cmd::Undo(1)), ); - // Map Shift-Return to insert a new line - bypass need for `\` continuation + // Map Ctrl-Enter to insert a new line - bypass need for `\` continuation rl.bind_sequence( - Event::KeySeq(smallvec![KeyEvent( - KeyCode::Char('m'), - Modifiers::CTRL_SHIFT - )]), + Event::KeySeq(smallvec![KeyEvent(KeyCode::Char('J'), Modifiers::CTRL)]), EventHandler::Simple(Cmd::Newline), ); rl.bind_sequence( - Event::KeySeq(smallvec![KeyEvent( - KeyCode::Char('j'), - Modifiers::CTRL_SHIFT - )]), - EventHandler::Simple(Cmd::Newline), - ); - rl.bind_sequence( - Event::KeySeq(smallvec![KeyEvent(KeyCode::Enter, Modifiers::SHIFT)]), + Event::KeySeq(smallvec![KeyEvent(KeyCode::Enter, Modifiers::CTRL)]), EventHandler::Simple(Cmd::Newline), ); // Map Ctrl-Home and Ctrl-End for beginning/end of input