diff --git a/crates/rune-macros/src/any.rs b/crates/rune-macros/src/any.rs index a71168663..fdcbd46b8 100644 --- a/crates/rune-macros/src/any.rs +++ b/crates/rune-macros/src/any.rs @@ -504,7 +504,7 @@ where let Tokens { alloc, - any, + any_t, box_, context_error, from_value, @@ -574,31 +574,20 @@ where } }; - let impl_type_of = if attr.builtin.is_none() { - let type_hash = type_hash.into_inner(); - - let make_hash = if !generic_names.is_empty() { - quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*]))) - } else { - quote!(#hash::new(#type_hash)) - }; - - let type_parameters = - quote!(#hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*])); + let impl_type_of = if let Some(ty) = attr.static_type { + let ty_hash = syn::Ident::new(&format!("{ty}_HASH"), ty.span()); Some(quote! { #[automatically_derived] impl #impl_generics #type_hash_t for #ident #type_generics #where_clause { - const HASH: #hash = #make_hash; + const HASH: #hash = #static_type_mod::#ty_hash; } #[automatically_derived] impl #impl_generics #type_of for #ident #type_generics #where_clause { - const PARAMETERS: #hash = #type_parameters; - #[inline] fn type_info() -> #type_info { - #type_info::any::() + #type_info::static_type(#static_type_mod::#ty) } } @@ -608,25 +597,36 @@ where fn maybe_type_of() -> #alloc::Result<#meta::DocType> { #meta::DocType::with_generics( ::HASH, - [#(<#generic_names as #maybe_type_of>::maybe_type_of()?),*] + [#(<#generic_names as #maybe_type_of>::maybe_type_of()),*] ) } } }) - } else if let Some(ty) = attr.static_type { - let ty_hash = syn::Ident::new(&format!("{ty}_HASH"), ty.span()); + } else if attr.builtin.is_none() { + let type_hash = type_hash.into_inner(); + + let make_hash = if !generic_names.is_empty() { + quote!(#hash::new_with_type_parameters(#type_hash, #hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*]))) + } else { + quote!(#hash::new(#type_hash)) + }; + + let type_parameters = + quote!(#hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*])); Some(quote! { #[automatically_derived] impl #impl_generics #type_hash_t for #ident #type_generics #where_clause { - const HASH: #hash = #static_type_mod::#ty_hash; + const HASH: #hash = #make_hash; } #[automatically_derived] impl #impl_generics #type_of for #ident #type_generics #where_clause { + const PARAMETERS: #hash = #type_parameters; + #[inline] fn type_info() -> #type_info { - #type_info::static_type(#static_type_mod::#ty) + #type_info::any::() } } @@ -636,7 +636,7 @@ where fn maybe_type_of() -> #alloc::Result<#meta::DocType> { #meta::DocType::with_generics( ::HASH, - [#(<#generic_names as #maybe_type_of>::maybe_type_of()),*] + [#(<#generic_names as #maybe_type_of>::maybe_type_of()?),*] ) } } @@ -645,10 +645,10 @@ where None }; - let any = if attr.builtin.is_none() { - Some(quote! { + let non_builtin = attr.builtin.is_none().then(|| { + quote! { #[automatically_derived] - impl #impl_generics #any for #ident #type_generics #where_clause { + impl #impl_generics #any_t for #ident #type_generics #where_clause { } #[automatically_derived] @@ -698,10 +698,8 @@ where Option::<&str>::None } } - }) - } else { - None - }; + } + }); let impl_from_value = 'out: { if let Some(path) = attr.from_value { @@ -793,7 +791,7 @@ where #impl_from_value #impl_from_value_ref #impl_from_value_mut - #any + #non_builtin } } } diff --git a/crates/rune-macros/src/context.rs b/crates/rune-macros/src/context.rs index 497459099..e403a1f6a 100644 --- a/crates/rune-macros/src/context.rs +++ b/crates/rune-macros/src/context.rs @@ -613,7 +613,7 @@ impl Context { Tokens { alloc: path(m, ["alloc"]), - any: path(m, ["Any"]), + any_t: path(m, ["Any"]), box_: path(m, ["__private", "Box"]), compile_error: path(m, ["compile", "Error"]), context_error: path(m, ["compile", "ContextError"]), @@ -704,7 +704,7 @@ fn path(base: &syn::Path, path: [&'static str; N]) -> syn::Path pub(crate) struct Tokens { pub(crate) alloc: syn::Path, - pub(crate) any: syn::Path, + pub(crate) any_t: syn::Path, pub(crate) box_: syn::Path, pub(crate) compile_error: syn::Path, pub(crate) context_error: syn::Path, diff --git a/crates/rune/src/modules/ops.rs b/crates/rune/src/modules/ops.rs index c24b12618..3ed055811 100644 --- a/crates/rune/src/modules/ops.rs +++ b/crates/rune/src/modules/ops.rs @@ -86,7 +86,19 @@ pub fn module() -> Result { { m.ty::()?; - m.function_meta(RangeFull::contains)?; + m.function_meta(RangeFull::contains__meta)?; + + m.function_meta(RangeFull::partial_eq__meta)?; + m.implement_trait::(rune::item!(::std::cmp::PartialEq))?; + + m.function_meta(RangeFull::eq__meta)?; + m.implement_trait::(rune::item!(::std::cmp::Eq))?; + + m.function_meta(RangeFull::partial_cmp__meta)?; + m.implement_trait::(rune::item!(::std::cmp::PartialOrd))?; + + m.function_meta(RangeFull::cmp__meta)?; + m.implement_trait::(rune::item!(::std::cmp::Ord))?; } { diff --git a/crates/rune/src/modules/string.rs b/crates/rune/src/modules/string.rs index a291d354f..446813a0a 100644 --- a/crates/rune/src/modules/string.rs +++ b/crates/rune/src/modules/string.rs @@ -11,10 +11,11 @@ use crate::alloc::string::FromUtf8Error; use crate::alloc::{String, Vec}; use crate::compile::Named; use crate::runtime::{ - Bytes, FromValue, Function, Inline, MaybeTypeOf, Mutable, Panic, Ref, ToValue, TypeOf, Value, - ValueBorrowRef, VmErrorKind, VmResult, + Bytes, FromValue, Function, Inline, MaybeTypeOf, Mutable, Panic, Range, RangeFrom, RangeFull, + RangeInclusive, RangeTo, RangeToInclusive, Ref, ToValue, TypeOf, Value, ValueBorrowRef, + VmErrorKind, VmResult, }; -use crate::{Any, ContextError, Module}; +use crate::{Any, ContextError, Module, TypeHash}; /// Strings. /// @@ -1022,42 +1023,50 @@ fn chars(s: Ref) -> Chars { fn get(this: &str, key: Value) -> VmResult> { use crate::runtime::TypeOf; - let slice = match vm_try!(key.borrow_ref()) { - ValueBorrowRef::Mutable(value) => match &*value { - Mutable::RangeFrom(range) => { + let slice = match vm_try!(key.as_any()) { + Some(value) => match value.type_hash() { + RangeFrom::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); this.get(start..) } - Mutable::RangeFull(..) => this.get(..), - Mutable::RangeInclusive(range) => { + RangeFull::HASH => { + _ = vm_try!(value.borrow_ref::()); + this.get(..) + } + RangeInclusive::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); let end = vm_try!(range.end.as_usize()); this.get(start..=end) } - Mutable::RangeToInclusive(range) => { + RangeToInclusive::HASH => { + let range = vm_try!(value.borrow_ref::()); let end = vm_try!(range.end.as_usize()); this.get(..=end) } - Mutable::RangeTo(range) => { + RangeTo::HASH => { + let range = vm_try!(value.borrow_ref::()); let end = vm_try!(range.end.as_usize()); this.get(..end) } - Mutable::Range(range) => { + Range::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); let end = vm_try!(range.end.as_usize()); this.get(start..end) } - index => { + _ => { return VmResult::err(VmErrorKind::UnsupportedIndexGet { target: String::type_info(), - index: index.type_info(), + index: value.type_info(), }) } }, - index => { + _ => { return VmResult::err(VmErrorKind::UnsupportedIndexGet { target: String::type_info(), - index: index.type_info(), + index: vm_try!(key.type_info()), }) } }; diff --git a/crates/rune/src/runtime/any_obj.rs b/crates/rune/src/runtime/any_obj.rs index d9ee46d87..69825a7fa 100644 --- a/crates/rune/src/runtime/any_obj.rs +++ b/crates/rune/src/runtime/any_obj.rs @@ -13,19 +13,41 @@ use super::{ RefVtable, Snapshot, TypeInfo, VmErrorKind, }; -/// Errors caused by casting an any reference. -#[cfg_attr(test, derive(Debug, PartialEq))] -pub(crate) enum AnyObjError { - Cast(TypeInfo), +/// Errors caused when accessing or coercing an [`AnyObj`]. +#[cfg_attr(test, derive(PartialEq))] +pub struct AnyObjError { + kind: AnyObjErrorKind, +} + +impl AnyObjError { + fn new(kind: AnyObjErrorKind) -> Self { + Self { kind } + } + + #[inline] + pub(super) fn into_kind(self) -> AnyObjErrorKind { + self.kind + } +} + +#[derive(Debug)] +#[cfg_attr(test, derive(PartialEq))] +pub(super) enum AnyObjErrorKind { + Cast(AnyTypeInfo, TypeInfo), AccessError(AccessError), } -impl From for AnyObjError -where - AccessError: From, -{ - fn from(value: T) -> Self { - AnyObjError::AccessError(AccessError::from(value)) +impl fmt::Debug for AnyObjError { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.kind.fmt(f) + } +} + +impl From for AnyObjError { + #[inline] + fn from(error: AccessError) -> Self { + Self::new(AnyObjErrorKind::AccessError(error)) } } @@ -178,11 +200,14 @@ impl AnyObj { let vtable = vtable(&self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } if !matches!(vtable.kind, Kind::Own) { - return Err(AnyObjError::AccessError(AccessError::not_owned( + return Err(AnyObjError::from(AccessError::not_owned( vtable.type_info(), ))); } @@ -238,18 +263,21 @@ impl AnyObj { /// /// This errors in case the underlying value is not owned, non-owned /// references cannot be coerced into [`Ref`]. - pub(crate) fn downcast_ref(self) -> Result, AnyObjError> + pub(crate) fn into_ref(self) -> Result, AnyObjError> where T: Any, { let vtable = vtable(&self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } if !matches!(vtable.kind, Kind::Own) { - return Err(AnyObjError::AccessError(AccessError::not_owned( + return Err(AnyObjError::from(AccessError::not_owned( vtable.type_info(), ))); } @@ -279,18 +307,21 @@ impl AnyObj { /// /// This errors in case the underlying value is not owned, non-owned /// references cannot be coerced into [`Mut`]. - pub(crate) fn downcast_mut(self) -> Result, AnyObjError> + pub(crate) fn into_mut(self) -> Result, AnyObjError> where T: Any, { let vtable = vtable(&self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } if !matches!(vtable.kind, Kind::Own) { - return Err(AnyObjError::AccessError(AccessError::not_owned( + return Err(AnyObjError::from(AccessError::not_owned( vtable.type_info(), ))); } @@ -318,14 +349,17 @@ impl AnyObj { /// /// This prevents other exclusive accesses from being performed while the /// guard returned from this function is live. - pub(crate) fn downcast_borrow_ref(&self) -> Result, AnyObjError> + pub fn borrow_ref(&self) -> Result, AnyObjError> where T: Any, { let vtable = vtable(self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } // SAFETY: We've checked for the appropriate type just above. @@ -336,18 +370,50 @@ impl AnyObj { } } + /// Returns some mutable reference to the boxed value if it is of type `T`. + pub fn borrow_mut(&self) -> Result, AnyObjError> + where + T: Any, + { + let vtable = vtable(self); + + if (vtable.type_id)() != TypeId::of::() { + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); + } + + if matches!(vtable.kind, Kind::Ref) { + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); + } + + // SAFETY: We've checked for the appropriate type just above. + unsafe { + let guard = self.shared.as_ref().access.exclusive()?; + let data = vtable.as_ptr(self.shared); + Ok(BorrowMut::new(data, guard)) + } + } + /// Get a reference to the interior value while checking for shared access. /// /// This prevents other exclusive accesses from being performed while the /// guard returned from this function is live. - pub(crate) fn downcast_borrow_ptr(self) -> Result<(NonNull, RawAnyObjGuard), AnyObjError> + pub(crate) fn borrow_ref_ptr(self) -> Result<(NonNull, RawAnyObjGuard), AnyObjError> where T: Any, { let vtable = vtable(&self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } // SAFETY: We've checked for the appropriate type just above. @@ -369,43 +435,24 @@ impl AnyObj { } /// Returns some mutable reference to the boxed value if it is of type `T`. - pub(crate) fn downcast_borrow_mut(&self) -> Result, AnyObjError> - where - T: Any, - { - let vtable = vtable(self); - - if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); - } - - if matches!(vtable.kind, Kind::Ref) { - return Err(AnyObjError::Cast(vtable.type_info())); - } - - // SAFETY: We've checked for the appropriate type just above. - unsafe { - let guard = self.shared.as_ref().access.exclusive()?; - let data = vtable.as_ptr(self.shared); - Ok(BorrowMut::new(data, guard)) - } - } - - /// Returns some mutable reference to the boxed value if it is of type `T`. - pub(crate) fn downcast_borrow_mut_ptr( - self, - ) -> Result<(NonNull, RawAnyObjGuard), AnyObjError> + pub(crate) fn borrow_mut_ptr(self) -> Result<(NonNull, RawAnyObjGuard), AnyObjError> where T: Any, { let vtable = vtable(&self); if (vtable.type_id)() != TypeId::of::() { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } if matches!(vtable.kind, Kind::Ref) { - return Err(AnyObjError::Cast(vtable.type_info())); + return Err(AnyObjError::new(AnyObjErrorKind::Cast( + T::INFO, + vtable.type_info(), + ))); } // SAFETY: We've checked for the appropriate type just above. diff --git a/crates/rune/src/runtime/mod.rs b/crates/rune/src/runtime/mod.rs index 352fbf82f..2058565dd 100644 --- a/crates/rune/src/runtime/mod.rs +++ b/crates/rune/src/runtime/mod.rs @@ -21,8 +21,9 @@ mod borrow_ref; pub use self::borrow_ref::BorrowRef; mod any_obj; -pub use self::any_obj::AnyObj; -pub(crate) use self::any_obj::{AnyObjDrop, AnyObjError, RawAnyObjGuard}; +use self::any_obj::AnyObjErrorKind; +pub use self::any_obj::{AnyObj, AnyObjError}; +pub(crate) use self::any_obj::{AnyObjDrop, RawAnyObjGuard}; mod args; pub use self::args::{Args, FixedArgs}; diff --git a/crates/rune/src/runtime/range.rs b/crates/rune/src/runtime/range.rs index d65d6d7de..0571a52f3 100644 --- a/crates/rune/src/runtime/range.rs +++ b/crates/rune/src/runtime/range.rs @@ -57,8 +57,7 @@ use super::StepsBetween; /// ``` #[derive(Any, Clone, TryClone)] #[try_clone(crate)] -#[rune(builtin, constructor, static_type = RANGE)] -#[rune(from_value = Value::into_range, from_value_ref = Value::into_range_ref, from_value_mut = Value::into_range_mut)] +#[rune(constructor, static_type = RANGE)] pub struct Range { /// The start value of the range. #[rune(get, set)] @@ -308,7 +307,7 @@ where let start = vm_try!(self.start.to_value()); let end = vm_try!(self.end.to_value()); let range = Range::new(start, end); - VmResult::Ok(vm_try!(Value::try_from(range))) + VmResult::Ok(vm_try!(Value::new(range))) } } @@ -318,7 +317,7 @@ where { #[inline] fn from_value(value: Value) -> VmResult { - let range = vm_try!(value.into_range()); + let range = vm_try!(value.into_any::()); let start = vm_try!(Idx::from_value(range.start)); let end = vm_try!(Idx::from_value(range.end)); VmResult::Ok(ops::Range { start, end }) diff --git a/crates/rune/src/runtime/range_from.rs b/crates/rune/src/runtime/range_from.rs index 9ba922cc4..c0354a460 100644 --- a/crates/rune/src/runtime/range_from.rs +++ b/crates/rune/src/runtime/range_from.rs @@ -52,8 +52,7 @@ use crate::Any; /// ``` #[derive(Any, Clone, TryClone)] #[try_clone(crate)] -#[rune(builtin, constructor, static_type = RANGE_FROM)] -#[rune(from_value = Value::into_range_from, from_value_ref = Value::into_range_from_ref, from_value_mut = Value::into_range_from_mut)] +#[rune(constructor, static_type = RANGE_FROM)] pub struct RangeFrom { /// The start value of the range. #[rune(get, set)] @@ -278,7 +277,7 @@ where fn to_value(self) -> VmResult { let start = vm_try!(self.start.to_value()); let range = RangeFrom::new(start); - VmResult::Ok(vm_try!(Value::try_from(range))) + VmResult::Ok(vm_try!(Value::new(range))) } } @@ -288,7 +287,7 @@ where { #[inline] fn from_value(value: Value) -> VmResult { - let range = vm_try!(value.into_range_from()); + let range = vm_try!(value.into_any::()); let start = vm_try!(Idx::from_value(range.start)); VmResult::Ok(ops::RangeFrom { start }) } diff --git a/crates/rune/src/runtime/range_full.rs b/crates/rune/src/runtime/range_full.rs index 4354ac21e..7927bb22a 100644 --- a/crates/rune/src/runtime/range_full.rs +++ b/crates/rune/src/runtime/range_full.rs @@ -4,7 +4,7 @@ use core::ops; use crate as rune; use crate::alloc::clone::TryClone; -use crate::runtime::{FromValue, ProtocolCaller, ToValue, Value, VmResult}; +use crate::runtime::{FromValue, ToValue, Value, VmResult}; use crate::Any; /// Type for a full range expression `..`. @@ -32,40 +32,15 @@ use crate::Any; /// ``` #[derive(Any, Default, Clone, TryClone)] #[try_clone(crate)] -#[rune(builtin, constructor, static_type = RANGE_FULL)] -#[rune(from_value = Value::into_range_full, from_value_ref = Value::into_range_full_ref, from_value_mut = Value::into_range_full_mut)] +#[rune(constructor, static_type = RANGE_FULL)] pub struct RangeFull; impl RangeFull { - /// Construct a new range. + /// Construct a new full range. pub const fn new() -> Self { Self } - pub(crate) fn partial_eq_with( - _: &Self, - _: &Self, - _: &mut dyn ProtocolCaller, - ) -> VmResult { - VmResult::Ok(true) - } - - pub(crate) fn eq_with(_: &Self, _: &Self, _: &mut dyn ProtocolCaller) -> VmResult { - VmResult::Ok(true) - } - - pub(crate) fn partial_cmp_with( - _: &Self, - _: &Self, - _: &mut dyn ProtocolCaller, - ) -> VmResult> { - VmResult::Ok(Some(Ordering::Equal)) - } - - pub(crate) fn cmp_with(_: &Self, _: &Self, _: &mut dyn ProtocolCaller) -> VmResult { - VmResult::Ok(Ordering::Equal) - } - /// Test if the range contains the given value. /// /// The check is performed using the [`PARTIAL_CMP`] protocol. @@ -82,10 +57,66 @@ impl RangeFull { /// /// assert!(range is std::ops::RangeFull); /// ``` - #[rune::function] + #[rune::function(keep)] pub(crate) fn contains(&self, _: Value) -> VmResult { VmResult::Ok(true) } + + /// Test the full range for partial equality. + /// + /// # Examples + /// + /// ```rune + /// let range = ..; + /// assert!(range == ..); + /// ``` + #[rune::function(keep, protocol = PARTIAL_EQ)] + pub fn partial_eq(&self, _: &Self) -> VmResult { + VmResult::Ok(true) + } + + /// Test the full range for total equality. + /// + /// # Examples + /// + /// ```rune + /// use std::ops::eq; + /// + /// let range = ..; + /// assert!(eq(range, ..)); + /// ``` + #[rune::function(keep, protocol = EQ)] + pub fn eq(&self, _: &Self) -> VmResult { + VmResult::Ok(true) + } + + /// Test the full range for partial ordering. + /// + /// # Examples + /// + /// ```rune + /// assert!(!((..) < (..))); + /// assert!(!((..) > (..))); + /// ``` + #[rune::function(keep, protocol = PARTIAL_CMP)] + pub fn partial_cmp(&self, _: &Self) -> VmResult> { + VmResult::Ok(Some(Ordering::Equal)) + } + + /// Test the full range for total ordering. + /// + /// # Examples + /// + /// ```rune + /// use std::ops::cmp; + /// use std::cmp::Ordering; + /// + /// assert_eq!(cmp(.., ..), Ordering::Equal); + /// ``` + #[rune::function(keep, protocol = CMP)] + pub fn cmp(&self, _: &Self) -> VmResult { + VmResult::Ok(Ordering::Equal) + } } impl fmt::Debug for RangeFull { @@ -97,14 +128,14 @@ impl fmt::Debug for RangeFull { impl ToValue for ops::RangeFull { fn to_value(self) -> VmResult { let range = RangeFull::new(); - VmResult::Ok(vm_try!(Value::try_from(range))) + VmResult::Ok(vm_try!(Value::new(range))) } } impl FromValue for ops::RangeFull { #[inline] fn from_value(value: Value) -> VmResult { - let RangeFull = vm_try!(value.into_range_full()); + let RangeFull = vm_try!(value.into_any::()); VmResult::Ok(ops::RangeFull) } } diff --git a/crates/rune/src/runtime/range_inclusive.rs b/crates/rune/src/runtime/range_inclusive.rs index e588af48d..cde378972 100644 --- a/crates/rune/src/runtime/range_inclusive.rs +++ b/crates/rune/src/runtime/range_inclusive.rs @@ -58,8 +58,7 @@ use super::StepsBetween; /// ``` #[derive(Any, Clone, TryClone)] #[try_clone(crate)] -#[rune(builtin, constructor, static_type = RANGE_INCLUSIVE)] -#[rune(from_value = Value::into_range_inclusive, from_value_ref = Value::into_range_inclusive_ref, from_value_mut = Value::into_range_inclusive_mut)] +#[rune(constructor, static_type = RANGE_INCLUSIVE)] pub struct RangeInclusive { /// The start value of the range. #[rune(get, set)] @@ -309,7 +308,7 @@ where let (start, end) = self.into_inner(); let start = vm_try!(start.to_value()); let end = vm_try!(end.to_value()); - VmResult::Ok(vm_try!(Value::try_from(RangeInclusive::new(start, end)))) + VmResult::Ok(vm_try!(Value::new(RangeInclusive::new(start, end)))) } } @@ -319,7 +318,7 @@ where { #[inline] fn from_value(value: Value) -> VmResult { - let range = vm_try!(value.into_range_inclusive()); + let range = vm_try!(value.into_any::()); let start = vm_try!(Idx::from_value(range.start)); let end = vm_try!(Idx::from_value(range.end)); VmResult::Ok(start..=end) diff --git a/crates/rune/src/runtime/range_to.rs b/crates/rune/src/runtime/range_to.rs index 9bf27801f..930954fb2 100644 --- a/crates/rune/src/runtime/range_to.rs +++ b/crates/rune/src/runtime/range_to.rs @@ -42,8 +42,7 @@ use crate::Any; #[derive(Any, Clone, TryClone)] #[try_clone(crate)] #[rune(crate)] -#[rune(builtin, constructor, static_type = RANGE_TO)] -#[rune(from_value = Value::into_range_to, from_value_ref = Value::into_range_to_ref, from_value_mut = Value::into_range_to_mut)] +#[rune(constructor, static_type = RANGE_TO)] pub struct RangeTo { /// The end value of the range. #[rune(get, set)] @@ -191,7 +190,7 @@ where { fn to_value(self) -> VmResult { let end = vm_try!(self.end.to_value()); - VmResult::Ok(vm_try!(Value::try_from(RangeTo::new(end)))) + VmResult::Ok(vm_try!(Value::new(RangeTo::new(end)))) } } @@ -201,7 +200,7 @@ where { #[inline] fn from_value(value: Value) -> VmResult { - let range = vm_try!(value.into_range_to()); + let range = vm_try!(value.into_any::()); let end = vm_try!(Idx::from_value(range.end)); VmResult::Ok(ops::RangeTo { end }) } diff --git a/crates/rune/src/runtime/range_to_inclusive.rs b/crates/rune/src/runtime/range_to_inclusive.rs index ec9b65e3b..c3b8627de 100644 --- a/crates/rune/src/runtime/range_to_inclusive.rs +++ b/crates/rune/src/runtime/range_to_inclusive.rs @@ -40,8 +40,7 @@ use crate::Any; /// # Ok::<_, rune::support::Error>(()) /// ``` #[derive(Any, Clone, TryClone)] -#[rune(builtin, constructor, static_type = RANGE_TO_INCLUSIVE)] -#[rune(from_value = Value::into_range_to_inclusive, from_value_ref = Value::into_range_to_inclusive_ref, from_value_mut = Value::into_range_to_inclusive_mut)] +#[rune(constructor, static_type = RANGE_TO_INCLUSIVE)] pub struct RangeToInclusive { /// The end value of the range. #[rune(get, set)] @@ -189,7 +188,7 @@ where { fn to_value(self) -> VmResult { let end = vm_try!(self.end.to_value()); - VmResult::Ok(vm_try!(Value::try_from(RangeToInclusive::new(end)))) + VmResult::Ok(vm_try!(Value::new(RangeToInclusive::new(end)))) } } @@ -199,7 +198,7 @@ where { #[inline] fn from_value(value: Value) -> VmResult { - let range = vm_try!(value.into_range_to_inclusive()); + let range = vm_try!(value.into_any::()); let end = vm_try!(Idx::from_value(range.end)); VmResult::Ok(ops::RangeToInclusive { end }) } diff --git a/crates/rune/src/runtime/tests.rs b/crates/rune/src/runtime/tests.rs index ff07ed1ab..7af4e6e2f 100644 --- a/crates/rune/src/runtime/tests.rs +++ b/crates/rune/src/runtime/tests.rs @@ -57,13 +57,13 @@ fn test_from_ref() -> Result<()> { unsafe { let (value, guard) = Value::from_ref(&value)?; - assert!(value.downcast_borrow_mut::().is_err()); - assert_eq!(10u32, value.downcast_borrow_ref::()?.0); + assert!(value.borrow_any_mut::().is_err()); + assert_eq!(10u32, value.borrow_any_ref::()?.0); drop(guard); - assert!(value.downcast_borrow_mut::().is_err()); - assert!(value.downcast_borrow_ref::().is_err()); + assert!(value.borrow_any_mut::().is_err()); + assert!(value.borrow_any_ref::().is_err()); } Ok(()) @@ -75,15 +75,15 @@ fn test_from_mut() -> Result<()> { unsafe { let (value, guard) = Value::from_mut(&mut value)?; - value.downcast_borrow_mut::()?.0 = 20; + value.borrow_any_mut::()?.0 = 20; - assert_eq!(20u32, value.downcast_borrow_mut::()?.0); - assert_eq!(20u32, value.downcast_borrow_ref::()?.0); + assert_eq!(20u32, value.borrow_any_mut::()?.0); + assert_eq!(20u32, value.borrow_any_ref::()?.0); drop(guard); - assert!(value.downcast_borrow_mut::().is_err()); - assert!(value.downcast_borrow_ref::().is_err()); + assert!(value.borrow_any_mut::().is_err()); + assert!(value.borrow_any_ref::().is_err()); } Ok(()) @@ -338,18 +338,18 @@ fn any_ref_from_own() { let v = Thing(1u32); let any = AnyObj::new(v).unwrap(); - let b = any.downcast_borrow_ref::().unwrap(); + let b = any.borrow_ref::().unwrap(); assert_eq!(b.0, 1u32); drop(b); - let mut b = any.downcast_borrow_mut::().unwrap(); + let mut b = any.borrow_mut::().unwrap(); b.0 += 1; assert_eq!(b.0, 2u32); - assert!(any.downcast_borrow_ref::().is_err()); + assert!(any.borrow_ref::().is_err()); drop(b); - let b = any.downcast_borrow_ref::().unwrap(); + let b = any.borrow_ref::().unwrap(); assert_eq!(b.0, 2u32); drop(b); @@ -363,18 +363,18 @@ fn any_ref_from_own_boxed() { let v = Boxed(Box::new(1u32)); let any = AnyObj::new(v).unwrap(); - let b = any.downcast_borrow_ref::().unwrap(); + let b = any.borrow_ref::().unwrap(); assert_eq!(*b.0, 1u32); drop(b); - let mut b = any.downcast_borrow_mut::().unwrap(); + let mut b = any.borrow_mut::().unwrap(); *b.0 += 1; assert_eq!(*b.0, 2u32); - assert!(any.downcast_borrow_ref::().is_err()); + assert!(any.borrow_ref::().is_err()); drop(b); - let b = any.downcast_borrow_ref::().unwrap(); + let b = any.borrow_ref::().unwrap(); assert_eq!(*b.0, 2u32); drop(b); @@ -387,7 +387,7 @@ fn any_ref_from_ref() { let v = Thing(1u32); let any = unsafe { AnyObj::from_ref(&v).unwrap() }; - let b = any.downcast_borrow_ref::().unwrap(); + let b = any.borrow_ref::().unwrap(); assert_eq!(b.0, 1u32); drop(b); @@ -400,10 +400,7 @@ fn any_ref_downcast_borrow_ref() { let any = unsafe { AnyObj::from_ref(&t).unwrap() }; - assert_eq!( - Ok(&Thing(1u32)), - any.downcast_borrow_ref::().as_deref() - ); + assert_eq!(Ok(&Thing(1u32)), any.borrow_ref::().as_deref()); assert!(any.downcast::().is_err()); } @@ -413,7 +410,7 @@ fn any_ref_from_mut() { let mut v = Thing(1u32); let any = unsafe { AnyObj::from_mut(&mut v).unwrap() }; - any.downcast_borrow_mut::().unwrap().0 += 1; + any.borrow_mut::().unwrap().0 += 1; assert_eq!(v.0, 2); @@ -425,12 +422,9 @@ fn any_ref_downcast_borrow_mut() { let mut t = Thing(1u32); let any = unsafe { AnyObj::from_mut(&mut t).unwrap() }; - any.downcast_borrow_mut::().unwrap().0 = 2; + any.borrow_mut::().unwrap().0 = 2; - assert_eq!( - Ok(&Thing(2u32)), - any.downcast_borrow_ref::().as_deref() - ); + assert_eq!(Ok(&Thing(2u32)), any.borrow_ref::().as_deref()); assert!(any.downcast::().is_err()); } @@ -442,12 +436,12 @@ fn value_from_mut() { unsafe { let (any, guard) = Value::from_mut(&mut v).unwrap(); - if let Ok(mut v) = any.downcast_borrow_mut::() { + if let Ok(mut v) = any.borrow_any_mut::() { v.0 += 1; } drop(guard); - assert!(any.downcast_borrow_mut::().is_err()); + assert!(any.borrow_any_mut::().is_err()); drop(any); } diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index c8e349bb7..4b341f5a8 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -23,11 +23,10 @@ use crate::compile::meta; use crate::runtime::static_type; use crate::runtime::vm::CallResultOnly; use crate::runtime::{ - AccessError, AnyObj, AnyObjDrop, AnyObjError, BorrowMut, BorrowRef, Bytes, ConstValue, - ControlFlow, DynGuardedArgs, EnvProtocolCaller, Format, Formatter, FromValue, Function, Future, - Generator, GeneratorState, IntoOutput, Iterator, MaybeTypeOf, Mut, Object, OwnedTuple, - Protocol, ProtocolCaller, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, - RangeToInclusive, RawAnyObjGuard, Ref, RuntimeError, Shared, Snapshot, Stream, ToValue, Type, + AccessError, AnyObj, AnyObjDrop, BorrowMut, BorrowRef, Bytes, ConstValue, ControlFlow, + DynGuardedArgs, EnvProtocolCaller, Format, Formatter, FromValue, Function, Future, Generator, + GeneratorState, IntoOutput, Iterator, MaybeTypeOf, Mut, Object, OwnedTuple, Protocol, + ProtocolCaller, RawAnyObjGuard, Ref, RuntimeError, Shared, Snapshot, Stream, ToValue, Type, TypeInfo, Variant, Vec, Vm, VmErrorKind, VmIntegerRepr, VmResult, }; #[cfg(feature = "alloc")] @@ -148,6 +147,17 @@ pub struct Value { } impl Value { + /// Construct a value from a type that implements [`Any`] which owns the + /// underlying value. + pub fn new(data: T) -> alloc::Result + where + T: Any, + { + Ok(Self { + repr: Repr::Any(AnyObj::new(data)?), + }) + } + /// Construct an Any that wraps a pointer. /// /// # Safety @@ -187,7 +197,7 @@ impl Value { /// /// unsafe { /// let (any, guard) = Value::from_ref(&mut v)?; - /// let b = any.downcast_borrow_ref::().unwrap(); + /// let b = any.borrow_any_ref::().unwrap(); /// assert_eq!(b.0, 1u32); /// } /// # Ok::<_, rune::support::Error>(()) @@ -248,12 +258,12 @@ impl Value { /// unsafe { /// let (any, guard) = Value::from_mut(&mut v)?; /// - /// if let Ok(mut v) = any.downcast_borrow_mut::() { + /// if let Ok(mut v) = any.borrow_any_mut::() { /// v.0 += 1; /// } /// /// drop(guard); - /// assert!(any.downcast_borrow_mut::().is_err()); + /// assert!(any.borrow_any_mut::().is_err()); /// drop(any); /// } /// @@ -423,16 +433,6 @@ impl Value { Mutable::Vec(value) => Mutable::Vec(vm_try!(value.try_clone())), Mutable::Tuple(value) => Mutable::Tuple(vm_try!(value.try_clone())), Mutable::Object(value) => Mutable::Object(vm_try!(value.try_clone())), - Mutable::RangeFrom(value) => Mutable::RangeFrom(vm_try!(value.try_clone())), - Mutable::RangeFull(value) => Mutable::RangeFull(vm_try!(value.try_clone())), - Mutable::RangeInclusive(value) => { - Mutable::RangeInclusive(vm_try!(value.try_clone())) - } - Mutable::RangeToInclusive(value) => { - Mutable::RangeToInclusive(vm_try!(value.try_clone())) - } - Mutable::RangeTo(value) => Mutable::RangeTo(vm_try!(value.try_clone())), - Mutable::Range(value) => Mutable::Range(vm_try!(value.try_clone())), Mutable::ControlFlow(value) => Mutable::ControlFlow(vm_try!(value.try_clone())), Mutable::Stream(value) => Mutable::Stream(vm_try!(value.try_clone())), Mutable::Generator(value) => Mutable::Generator(vm_try!(value.try_clone())), @@ -518,24 +518,6 @@ impl Value { Mutable::Object(value) => { vm_write!(f, "{value:?}"); } - Mutable::RangeFrom(value) => { - vm_write!(f, "{value:?}"); - } - Mutable::RangeFull(value) => { - vm_write!(f, "{value:?}"); - } - Mutable::RangeInclusive(value) => { - vm_write!(f, "{value:?}"); - } - Mutable::RangeToInclusive(value) => { - vm_write!(f, "{value:?}"); - } - Mutable::RangeTo(value) => { - vm_write!(f, "{value:?}"); - } - Mutable::Range(value) => { - vm_write!(f, "{value:?}"); - } Mutable::ControlFlow(value) => { vm_try!(ControlFlow::string_debug_with(value, f, caller)); } @@ -972,66 +954,6 @@ impl Value { into_object, } - into! { - /// Coerce into a [`RangeFrom`]. - RangeFrom(RangeFrom), - into_range_from_ref, - into_range_from_mut, - borrow_range_from_ref, - borrow_range_from_mut, - into_range_from, - } - - into! { - /// Coerce into a [`RangeFull`]. - RangeFull(RangeFull), - into_range_full_ref, - into_range_full_mut, - borrow_range_full_ref, - borrow_range_full_mut, - into_range_full, - } - - into! { - /// Coerce into a [`RangeToInclusive`]. - RangeToInclusive(RangeToInclusive), - into_range_to_inclusive_ref, - into_range_to_inclusive_mut, - borrow_range_to_inclusive_ref, - borrow_range_to_inclusive_mut, - into_range_to_inclusive, - } - - into! { - /// Coerce into a [`RangeInclusive`]. - RangeInclusive(RangeInclusive), - into_range_inclusive_ref, - into_range_inclusive_mut, - borrow_range_inclusive_ref, - borrow_range_inclusive_mut, - into_range_inclusive, - } - - into! { - /// Coerce into a [`RangeTo`]. - RangeTo(RangeTo), - into_range_to_ref, - into_range_to_mut, - borrow_range_to_ref, - borrow_range_to_mut, - into_range_to, - } - - into! { - /// Coerce into a [`Range`]. - Range(Range), - into_range_ref, - into_range_mut, - borrow_range_ref, - borrow_range_mut, - into_range, - } - into! { /// Coerce into a [`Stream`]. Stream(Stream), @@ -1099,13 +1021,7 @@ impl Value { ValueRepr::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_ref()?.type_info(), )), - ValueRepr::Any(value) => match value.downcast_ref() { - Ok(value) => Ok(value), - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRepr::Any(value) => Ok(value.into_ref()?), } } @@ -1125,16 +1041,11 @@ impl Value { ValueRepr::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_ref()?.type_info(), )), - ValueRepr::Any(value) => match value.downcast_borrow_ptr::() { - Ok((ptr, guard)) => { - let guard = RawValueGuard { guard }; - Ok((ptr, guard)) - } - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRepr::Any(value) => { + let (ptr, guard) = value.borrow_ref_ptr::()?; + let guard = RawValueGuard { guard }; + Ok((ptr, guard)) + } } } @@ -1149,13 +1060,7 @@ impl Value { ValueRepr::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_ref()?.type_info(), )), - ValueRepr::Any(value) => match value.downcast_mut() { - Ok(value) => Ok(value), - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRepr::Any(value) => Ok(value.into_mut()?), } } @@ -1175,22 +1080,17 @@ impl Value { ValueRepr::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_ref()?.type_info(), )), - ValueRepr::Any(value) => match value.downcast_borrow_mut_ptr::() { - Ok((ptr, guard)) => { - let guard = RawValueGuard { guard }; - Ok((ptr, guard)) - } - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRepr::Any(value) => { + let (ptr, guard) = value.borrow_mut_ptr::()?; + let guard = RawValueGuard { guard }; + Ok((ptr, guard)) + } } } /// Borrow the value as a typed reference. #[inline] - pub fn downcast_borrow_ref(&self) -> Result, RuntimeError> + pub fn borrow_any_ref(&self) -> Result, RuntimeError> where T: Any, { @@ -1199,19 +1099,13 @@ impl Value { ValueRef::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_ref()?.type_info(), )), - ValueRef::Any(value) => match value.downcast_borrow_ref() { - Ok(value) => Ok(value), - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRef::Any(value) => Ok(value.borrow_ref()?), } } /// Borrow the value as a mutable typed reference. #[inline] - pub fn downcast_borrow_mut(&self) -> Result, RuntimeError> + pub fn borrow_any_mut(&self) -> Result, RuntimeError> where T: Any, { @@ -1220,13 +1114,7 @@ impl Value { ValueRef::Mutable(value) => Err(RuntimeError::expected_any::( value.borrow_mut()?.type_info(), )), - ValueRef::Any(value) => match value.downcast_borrow_mut() { - Ok(value) => Ok(value), - Err(AnyObjError::Cast(type_info)) => { - Err(RuntimeError::expected_any::(type_info)) - } - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - }, + ValueRef::Any(value) => Ok(value.borrow_mut()?), } } @@ -1241,11 +1129,7 @@ impl Value { actual => return Err(RuntimeError::expected_any::(actual.type_info())), }; - match value.downcast::() { - Ok(value) => Ok(value), - Err(AnyObjError::Cast(type_info)) => Err(RuntimeError::expected_any::(type_info)), - Err(AnyObjError::AccessError(error)) => Err(RuntimeError::from(error)), - } + Ok(value.downcast::()?) } /// Get the type hash for the current value. @@ -1312,24 +1196,6 @@ impl Value { (Mutable::Bytes(a), Mutable::Bytes(b)) => { return VmResult::Ok(*a == *b); } - (Mutable::RangeFrom(a), Mutable::RangeFrom(b)) => { - return RangeFrom::partial_eq_with(a, b, caller); - } - (Mutable::RangeFull(a), Mutable::RangeFull(b)) => { - return RangeFull::partial_eq_with(a, b, caller); - } - (Mutable::RangeInclusive(a), Mutable::RangeInclusive(b)) => { - return RangeInclusive::partial_eq_with(a, b, caller); - } - (Mutable::RangeToInclusive(a), Mutable::RangeToInclusive(b)) => { - return RangeToInclusive::partial_eq_with(a, b, caller); - } - (Mutable::RangeTo(a), Mutable::RangeTo(b)) => { - return RangeTo::partial_eq_with(a, b, caller); - } - (Mutable::Range(a), Mutable::Range(b)) => { - return Range::partial_eq_with(a, b, caller); - } (Mutable::ControlFlow(a), Mutable::ControlFlow(b)) => { return ControlFlow::partial_eq_with(a, b, caller); } @@ -1535,24 +1401,6 @@ impl Value { (Mutable::Object(a), Mutable::Object(b)) => { return Object::eq_with(a, b, Value::eq_with, caller); } - (Mutable::RangeFrom(a), Mutable::RangeFrom(b)) => { - return RangeFrom::eq_with(a, b, caller); - } - (Mutable::RangeFull(a), Mutable::RangeFull(b)) => { - return RangeFull::eq_with(a, b, caller); - } - (Mutable::RangeInclusive(a), Mutable::RangeInclusive(b)) => { - return RangeInclusive::eq_with(a, b, caller); - } - (Mutable::RangeToInclusive(a), Mutable::RangeToInclusive(b)) => { - return RangeToInclusive::eq_with(a, b, caller); - } - (Mutable::RangeTo(a), Mutable::RangeTo(b)) => { - return RangeTo::eq_with(a, b, caller); - } - (Mutable::Range(a), Mutable::Range(b)) => { - return Range::eq_with(a, b, caller); - } (Mutable::ControlFlow(a), Mutable::ControlFlow(b)) => { return ControlFlow::eq_with(a, b, caller); } @@ -1659,24 +1507,6 @@ impl Value { (Mutable::Object(a), Mutable::Object(b)) => { return Object::partial_cmp_with(a, b, caller); } - (Mutable::RangeFrom(a), Mutable::RangeFrom(b)) => { - return RangeFrom::partial_cmp_with(a, b, caller); - } - (Mutable::RangeFull(a), Mutable::RangeFull(b)) => { - return RangeFull::partial_cmp_with(a, b, caller); - } - (Mutable::RangeInclusive(a), Mutable::RangeInclusive(b)) => { - return RangeInclusive::partial_cmp_with(a, b, caller); - } - (Mutable::RangeToInclusive(a), Mutable::RangeToInclusive(b)) => { - return RangeToInclusive::partial_cmp_with(a, b, caller); - } - (Mutable::RangeTo(a), Mutable::RangeTo(b)) => { - return RangeTo::partial_cmp_with(a, b, caller); - } - (Mutable::Range(a), Mutable::Range(b)) => { - return Range::partial_cmp_with(a, b, caller); - } (Mutable::EmptyStruct(a), Mutable::EmptyStruct(b)) => { if a.rtti.hash == b.rtti.hash { // NB: don't get any future ideas, this must fall through to @@ -1775,24 +1605,6 @@ impl Value { (Mutable::Object(a), Mutable::Object(b)) => { return Object::cmp_with(a, b, caller); } - (Mutable::RangeFrom(a), Mutable::RangeFrom(b)) => { - return RangeFrom::cmp_with(a, b, caller); - } - (Mutable::RangeFull(a), Mutable::RangeFull(b)) => { - return RangeFull::cmp_with(a, b, caller); - } - (Mutable::RangeInclusive(a), Mutable::RangeInclusive(b)) => { - return RangeInclusive::cmp_with(a, b, caller); - } - (Mutable::RangeToInclusive(a), Mutable::RangeToInclusive(b)) => { - return RangeToInclusive::cmp_with(a, b, caller); - } - (Mutable::RangeTo(a), Mutable::RangeTo(b)) => { - return RangeTo::cmp_with(a, b, caller); - } - (Mutable::Range(a), Mutable::Range(b)) => { - return Range::cmp_with(a, b, caller); - } (Mutable::EmptyStruct(a), Mutable::EmptyStruct(b)) => { if a.rtti.hash == b.rtti.hash { // NB: don't get any future ideas, this must fall through to @@ -1899,6 +1711,9 @@ impl Value { } } + /// Coerce into a checked [`Inline`] object. + /// + /// Any empty value will cause an access error. pub(crate) fn as_inline(&self) -> Result, AccessError> { match &self.repr { Repr::Inline(value) => Ok(Some(value)), @@ -1917,6 +1732,18 @@ impl Value { } } + /// Coerce into a checked [`AnyObj`] object. + /// + /// Any empty value will cause an access error. + pub(crate) fn as_any(&self) -> Result, AccessError> { + match &self.repr { + Repr::Inline(..) => Ok(None), + Repr::Mutable(..) => Ok(None), + Repr::Any(value) => Ok(Some(value)), + Repr::Empty => Err(AccessError::empty()), + } + } + pub(crate) fn take_value(self) -> Result { match self.repr { Repr::Inline(value) => Ok(OwnedValue::Inline(value)), @@ -2162,12 +1989,6 @@ from! { Tuple => OwnedTuple, Generator => Generator, Format => Format, - RangeFrom => RangeFrom, - RangeFull => RangeFull, - RangeInclusive => RangeInclusive, - RangeToInclusive => RangeToInclusive, - RangeTo => RangeTo, - Range => Range, Future => Future, Stream => Stream, } @@ -2452,18 +2273,6 @@ pub(crate) enum Mutable { Tuple(OwnedTuple), /// An object. Object(Object), - /// A range `start..` - RangeFrom(RangeFrom), - /// A full range `..` - RangeFull(RangeFull), - /// A full range `start..=end` - RangeInclusive(RangeInclusive), - /// A full range `..=end` - RangeToInclusive(RangeToInclusive), - /// A full range `..end` - RangeTo(RangeTo), - /// A range `start..end`. - Range(Range), /// A control flow indicator. ControlFlow(ControlFlow), /// A stored future. @@ -2500,12 +2309,6 @@ impl Mutable { Mutable::Vec(..) => TypeInfo::static_type(static_type::VEC), Mutable::Tuple(..) => TypeInfo::static_type(static_type::TUPLE), Mutable::Object(..) => TypeInfo::static_type(static_type::OBJECT), - Mutable::RangeFrom(..) => TypeInfo::static_type(static_type::RANGE_FROM), - Mutable::RangeFull(..) => TypeInfo::static_type(static_type::RANGE_FULL), - Mutable::RangeInclusive(..) => TypeInfo::static_type(static_type::RANGE_INCLUSIVE), - Mutable::RangeToInclusive(..) => TypeInfo::static_type(static_type::RANGE_TO_INCLUSIVE), - Mutable::RangeTo(..) => TypeInfo::static_type(static_type::RANGE_TO), - Mutable::Range(..) => TypeInfo::static_type(static_type::RANGE), Mutable::ControlFlow(..) => TypeInfo::static_type(static_type::CONTROL_FLOW), Mutable::Future(..) => TypeInfo::static_type(static_type::FUTURE), Mutable::Stream(..) => TypeInfo::static_type(static_type::STREAM), @@ -2533,12 +2336,6 @@ impl Mutable { Mutable::Vec(..) => static_type::VEC.hash, Mutable::Tuple(..) => static_type::TUPLE.hash, Mutable::Object(..) => static_type::OBJECT.hash, - Mutable::RangeFrom(..) => static_type::RANGE_FROM.hash, - Mutable::RangeFull(..) => static_type::RANGE_FULL.hash, - Mutable::RangeInclusive(..) => static_type::RANGE_INCLUSIVE.hash, - Mutable::RangeToInclusive(..) => static_type::RANGE_TO_INCLUSIVE.hash, - Mutable::RangeTo(..) => static_type::RANGE_TO.hash, - Mutable::Range(..) => static_type::RANGE.hash, Mutable::ControlFlow(..) => static_type::CONTROL_FLOW.hash, Mutable::Future(..) => static_type::FUTURE.hash, Mutable::Stream(..) => static_type::STREAM.hash, diff --git a/crates/rune/src/runtime/value/serde.rs b/crates/rune/src/runtime/value/serde.rs index 105264f74..bc5892e45 100644 --- a/crates/rune/src/runtime/value/serde.rs +++ b/crates/rune/src/runtime/value/serde.rs @@ -88,20 +88,6 @@ impl ser::Serialize for Value { Mutable::Format(..) => { Err(ser::Error::custom("cannot serialize format specifications")) } - Mutable::RangeFrom(..) => { - Err(ser::Error::custom("cannot serialize `start..` ranges")) - } - Mutable::RangeFull(..) => Err(ser::Error::custom("cannot serialize `..` ranges")), - Mutable::RangeInclusive(..) => { - Err(ser::Error::custom("cannot serialize `start..=end` ranges")) - } - Mutable::RangeToInclusive(..) => { - Err(ser::Error::custom("cannot serialize `..=end` ranges")) - } - Mutable::RangeTo(..) => Err(ser::Error::custom("cannot serialize `..end` ranges")), - Mutable::Range(..) => { - Err(ser::Error::custom("cannot serialize `start..end` ranges")) - } Mutable::ControlFlow(..) => { Err(ser::Error::custom("cannot serialize `start..end` ranges")) } diff --git a/crates/rune/src/runtime/vec.rs b/crates/rune/src/runtime/vec.rs index 7f4b6fac0..ab26a963e 100644 --- a/crates/rune/src/runtime/vec.rs +++ b/crates/rune/src/runtime/vec.rs @@ -12,11 +12,12 @@ use crate::alloc::prelude::*; use crate::runtime::slice::Iter; #[cfg(feature = "alloc")] use crate::runtime::Hasher; -use crate::runtime::{ - Formatter, FromValue, Mutable, ProtocolCaller, RawAnyGuard, Ref, ToValue, UnsafeToRef, Value, - ValueBorrowRef, VmErrorKind, VmResult, +use crate::{Any, TypeHash}; + +use super::{ + Formatter, FromValue, ProtocolCaller, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, + RangeToInclusive, RawAnyGuard, Ref, ToValue, UnsafeToRef, Value, VmErrorKind, VmResult, }; -use crate::Any; /// Struct representing a dynamic vector. /// @@ -352,27 +353,35 @@ impl Vec { /// types, such as vectors and tuples. pub(crate) fn index_get(this: &[Value], index: Value) -> VmResult> { let slice: Option<&[Value]> = 'out: { - if let ValueBorrowRef::Mutable(value) = vm_try!(index.borrow_ref()) { - match &*value { - Mutable::RangeFrom(range) => { + if let Some(value) = vm_try!(index.as_any()) { + match value.type_hash() { + RangeFrom::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); break 'out this.get(start..); } - Mutable::RangeFull(..) => break 'out this.get(..), - Mutable::RangeInclusive(range) => { + RangeFull::HASH => { + _ = vm_try!(value.borrow_ref::()); + break 'out this.get(..); + } + RangeInclusive::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); let end = vm_try!(range.end.as_usize()); break 'out this.get(start..=end); } - Mutable::RangeToInclusive(range) => { + RangeToInclusive::HASH => { + let range = vm_try!(value.borrow_ref::()); let end = vm_try!(range.end.as_usize()); break 'out this.get(..=end); } - Mutable::RangeTo(range) => { + RangeTo::HASH => { + let range = vm_try!(value.borrow_ref::()); let end = vm_try!(range.end.as_usize()); break 'out this.get(..end); } - Mutable::Range(range) => { + Range::HASH => { + let range = vm_try!(value.borrow_ref::()); let start = vm_try!(range.start.as_usize()); let end = vm_try!(range.end.as_usize()); break 'out this.get(start..end); diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 105282930..16e1a2cc0 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -2817,28 +2817,28 @@ impl Vm { let value = match range { InstRange::RangeFrom { start } => { let s = vm_try!(self.stack.at(start)).clone(); - vm_try!(Value::try_from(RangeFrom::new(s.clone()))) + vm_try!(Value::new(RangeFrom::new(s.clone()))) } InstRange::RangeFull => { - vm_try!(Value::try_from(RangeFull::new())) + vm_try!(Value::new(RangeFull::new())) } InstRange::RangeInclusive { start, end } => { let s = vm_try!(self.stack.at(start)).clone(); let e = vm_try!(self.stack.at(end)).clone(); - vm_try!(Value::try_from(RangeInclusive::new(s.clone(), e.clone()))) + vm_try!(Value::new(RangeInclusive::new(s.clone(), e.clone()))) } InstRange::RangeToInclusive { end } => { let e = vm_try!(self.stack.at(end)).clone(); - vm_try!(Value::try_from(RangeToInclusive::new(e.clone()))) + vm_try!(Value::new(RangeToInclusive::new(e.clone()))) } InstRange::RangeTo { end } => { let e = vm_try!(self.stack.at(end)).clone(); - vm_try!(Value::try_from(RangeTo::new(e.clone()))) + vm_try!(Value::new(RangeTo::new(e.clone()))) } InstRange::Range { start, end } => { let s = vm_try!(self.stack.at(start)).clone(); let e = vm_try!(self.stack.at(end)).clone(); - vm_try!(Value::try_from(Range::new(s.clone(), e.clone()))) + vm_try!(Value::new(Range::new(s.clone(), e.clone()))) } }; diff --git a/crates/rune/src/runtime/vm_error.rs b/crates/rune/src/runtime/vm_error.rs index 47e80b53b..094b7e2ec 100644 --- a/crates/rune/src/runtime/vm_error.rs +++ b/crates/rune/src/runtime/vm_error.rs @@ -10,8 +10,9 @@ use crate::alloc::{self, String}; use crate::compile::meta; use crate::runtime::unit::{BadInstruction, BadJump}; use crate::runtime::{ - AccessError, AccessErrorKind, BoxedPanic, CallFrame, DynArgsUsed, ExecutionState, MaybeTypeOf, - Panic, Protocol, SliceError, StackError, TypeInfo, TypeOf, Unit, Vm, VmHaltInfo, + AccessError, AccessErrorKind, AnyObjError, AnyObjErrorKind, BoxedPanic, CallFrame, DynArgsUsed, + ExecutionState, MaybeTypeOf, Panic, Protocol, SliceError, StackError, TypeInfo, TypeOf, Unit, + Vm, VmHaltInfo, }; use crate::{Any, Hash, ItemBuf}; @@ -492,6 +493,18 @@ impl RuntimeError { } } +impl From for RuntimeError { + fn from(value: AnyObjError) -> Self { + match value.into_kind() { + AnyObjErrorKind::Cast(expected, actual) => Self::new(VmErrorKind::Expected { + expected: TypeInfo::any_type_info(expected), + actual, + }), + AnyObjErrorKind::AccessError(error) => Self::from(error), + } + } +} + impl From for RuntimeError { #[inline] fn from(error: AccessError) -> Self { @@ -978,6 +991,13 @@ impl From for VmErrorKind { } } +impl From for VmErrorKind { + #[inline] + fn from(error: AnyObjError) -> Self { + Self::from(RuntimeError::from(error)) + } +} + impl From for VmErrorKind { #[inline] fn from(error: Infallible) -> Self {