diff --git a/crates/rune-core/src/hash.rs b/crates/rune-core/src/hash.rs index 5eb7cac06..69cc097d3 100644 --- a/crates/rune-core/src/hash.rs +++ b/crates/rune-core/src/hash.rs @@ -5,30 +5,75 @@ pub use self::to_type_hash::ToTypeHash; mod to_type_hash; use core::fmt; -use core::hash::{self, BuildHasher, BuildHasherDefault, Hash as _, Hasher}; +use core::hash::{BuildHasher, BuildHasherDefault, Hash as _, Hasher}; #[cfg(feature = "musli")] use musli::{Decode, Encode}; use serde::{Deserialize, Serialize}; use twox_hash::XxHash64; +#[derive(Debug)] +#[non_exhaustive] +pub struct TooManyParameters; + +impl fmt::Display for TooManyParameters { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Only 32 type parameters are supported") + } +} + +impl core::error::Error for TooManyParameters {} + use crate::protocol::Protocol; use crate::alloc; use crate::alloc::clone::TryClone; const SEP: u64 = 0x4bc94d6bd06053ad; -const PARAMS: u64 = 0x19893cc8f39b1371; const TYPE: u64 = 0x2fac10b63a6cc57c; const ASSOCIATED_FUNCTION_HASH: u64 = 0x5ea77ffbcdf5f302; const OBJECT_KEYS: u64 = 0x4473d7017aef7645; const IDENT: u64 = 0x1a095090689d4647; const INDEX: u64 = 0xe1b2378d7a937035; - // Salt for type parameters. const TYPE_PARAMETERS: u32 = 16; // Salt for function parameters. const FUNCTION_PARAMETERS: u32 = 48; +// A bunch of random hashes to mix in when calculating type parameters. +const PARAMETERS: [u64; 32] = [ + 0x2d859a05306ebe33, + 0x75ac929aabdda742, + 0x18f4e51cd6f60e86, + 0x3b47f977015b002, + 0xd7e3b9e36d59b900, + 0xad75a1d63593d47c, + 0x8fc37a65ac89ed71, + 0x39eb9ab133d1cf22, + 0xa287885efb6bf688, + 0x9eeef0c7395ea8ca, + 0x26a193328114c317, + 0x9edc35591d044a28, + 0xbfa4e9a8eca88b80, + 0x94a626c6aa89a686, + 0x95970296235c5b91, + 0xa8ab16ceff9068b8, + 0x153e675e2a27db85, + 0xa873a7e51dfe4205, + 0xde401d82396a7876, + 0x9dbbae67606eddc3, + 0x23d51f8018d09e74, + 0xb5bfa5d588fedcc6, + 0x9702480ba16eeb96, + 0x58549fb39441505c, + 0xd88078065e88667d, + 0x38a1d4efb147fe18, + 0xf712c95e9ffd1ba5, + 0x73c2249b2845a5e0, + 0x8079aff8b0833e20, + 0x7e708fb5e906bbb5, + 0x22d363b1d55a5eec, + 0x9e2d56cbbd4459f1, +]; /// The primitive hash that among other things is used to reference items, /// types, and native functions. @@ -164,18 +209,20 @@ impl Hash { } /// Hash type parameters. - pub fn parameters(parameters: I) -> Self - where - I: IntoIterator, - I::Item: hash::Hash, - { - let mut hasher = ParametersBuilder::new(); + pub const fn parameters(params: [Hash; N]) -> Self { + let mut builder = ParametersBuilder::new(); + + while builder.index < N { + let param = params[builder.index]; - for p in parameters { - hasher.add(p); + let Ok(b) = builder.add(param) else { + panic!("Only up to 32 type parameters are supported"); + }; + + builder = b; } - hasher.finish() + builder.finish() } /// Construct a new hasher. @@ -203,30 +250,65 @@ impl fmt::Debug for Hash { } /// Helper to build a parameters hash. -#[doc(hidden)] +/// +/// A collection of parameters are like the type parameters like `String` and +/// `i64` in a signature like: +/// +/// `::my_crate::Map` +/// +/// # Examples +/// +/// ``` +/// use rune::TypeHash; +/// use rune::hash::ParametersBuilder; +/// +/// let mut params = ParametersBuilder::new(); +/// +/// let params = params.add(String::HASH)?; +/// let params = params.add(i64::HASH)?; +/// +/// let hash = params.finish(); +/// # Ok::<_, rune::hash::TooManyParameters>(()) +/// ``` +#[derive(Default)] pub struct ParametersBuilder { - hasher: XxHash64, + base: u64, + index: usize, + shift: u32, } impl ParametersBuilder { - #[doc(hidden)] - pub fn new() -> Self { - let mut hasher = Hash::new_hasher(); - PARAMS.hash(&mut hasher); - Self { hasher } + /// Construct a new collection of parameters. + pub const fn new() -> Self { + Self { + base: 0, + index: 0, + shift: 0, + } } - #[doc(hidden)] - pub fn add

(&mut self, p: P) - where - P: hash::Hash, - { - SEP.hash(&mut self.hasher); - p.hash(&mut self.hasher); + /// Add a hash to the collection of parameters. + /// + /// # Errors + /// + /// Errors if too many parameters are added. + pub const fn add(mut self, Hash(hash): Hash) -> Result { + if self.index >= PARAMETERS.len() { + self.shift += 8; + self.index = 0; + + if self.shift >= u64::BITS { + return Err(TooManyParameters); + } + } + + self.base ^= hash ^ PARAMETERS[self.index].wrapping_shl(self.shift); + self.index += 1; + Ok(self) } - #[doc(hidden)] - pub fn finish(&self) -> Hash { - Hash::new(self.hasher.finish()) + /// Finish building the parameters hash. + pub const fn finish(self) -> Hash { + Hash::new(self.base) } } diff --git a/crates/rune-macros/src/any.rs b/crates/rune-macros/src/any.rs index c5b1db9b1..a71168663 100644 --- a/crates/rune-macros/src/any.rs +++ b/crates/rune-macros/src/any.rs @@ -504,11 +504,9 @@ where let Tokens { alloc, - any_type_info, any, box_, context_error, - core_type_of, from_value, hash, install_with, @@ -524,6 +522,7 @@ where ref_, static_type_mod, to_value, + type_hash_t, type_info, type_of, unsafe_to_mut, @@ -579,39 +578,27 @@ where 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 #core_type_of>::type_hash()),*]))) + 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 = if !generic_names.is_empty() { - quote!(#hash::parameters([#(<#generic_names as #core_type_of>::type_hash()),*])) - } else { - quote!(#hash::EMPTY) - }; + let type_parameters = + quote!(#hash::parameters([#(<#generic_names as #type_hash_t>::HASH),*])); Some(quote! { #[automatically_derived] - impl #impl_generics #core_type_of for #ident #type_generics #where_clause { - #[inline] - fn type_hash() -> #hash { - #make_hash - } + impl #impl_generics #type_hash_t for #ident #type_generics #where_clause { + const HASH: #hash = #make_hash; } #[automatically_derived] impl #impl_generics #type_of for #ident #type_generics #where_clause { - #[inline] - fn type_parameters() -> #hash { - #type_parameters - } + const PARAMETERS: #hash = #type_parameters; #[inline] fn type_info() -> #type_info { - #type_info::Any(#any_type_info::__private_new( - #raw_str::from_str(core::any::type_name::()), - ::type_hash(), - )) + #type_info::any::() } } @@ -620,27 +607,26 @@ where #[inline] fn maybe_type_of() -> #alloc::Result<#meta::DocType> { #meta::DocType::with_generics( - ::type_hash(), + ::HASH, [#(<#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()); + Some(quote! { #[automatically_derived] - impl #impl_generics #core_type_of for #ident #type_generics #where_clause { - #[inline] - fn type_hash() -> #hash { - #static_type_mod::#ty.hash - } + impl #impl_generics #type_hash_t for #ident #type_generics #where_clause { + const HASH: #hash = #static_type_mod::#ty_hash; } #[automatically_derived] impl #impl_generics #type_of for #ident #type_generics #where_clause { #[inline] fn type_info() -> #type_info { - #type_info::StaticType(#static_type_mod::#ty) + #type_info::static_type(#static_type_mod::#ty) } } @@ -649,7 +635,7 @@ where #[inline] fn maybe_type_of() -> #alloc::Result<#meta::DocType> { #meta::DocType::with_generics( - ::type_hash(), + ::HASH, [#(<#generic_names as #maybe_type_of>::maybe_type_of()),*] ) } diff --git a/crates/rune-macros/src/context.rs b/crates/rune-macros/src/context.rs index 608cffc63..497459099 100644 --- a/crates/rune-macros/src/context.rs +++ b/crates/rune-macros/src/context.rs @@ -613,12 +613,10 @@ impl Context { Tokens { alloc: path(m, ["alloc"]), - any_type_info: path(m, ["runtime", "AnyTypeInfo"]), any: path(m, ["Any"]), box_: path(m, ["__private", "Box"]), compile_error: path(m, ["compile", "Error"]), context_error: path(m, ["compile", "ContextError"]), - core_type_of: path(m, ["runtime", "CoreTypeOf"]), double_ended_iterator: path(&core, ["iter", "DoubleEndedIterator"]), from_value: path(m, ["runtime", "FromValue"]), hash: path(m, ["Hash"]), @@ -656,6 +654,7 @@ impl Context { try_clone: path(m, ["alloc", "clone", "TryClone"]), try_from: path(&core, ["convert", "TryFrom"]), tuple: path(m, ["runtime", "Tuple"]), + type_hash_t: path(m, ["runtime", "TypeHash"]), type_info: path(m, ["runtime", "TypeInfo"]), type_name: path(&core, ["any", "type_name"]), type_of: path(m, ["runtime", "TypeOf"]), @@ -705,12 +704,10 @@ fn path(base: &syn::Path, path: [&'static str; N]) -> syn::Path pub(crate) struct Tokens { pub(crate) alloc: syn::Path, - pub(crate) any_type_info: syn::Path, pub(crate) any: syn::Path, pub(crate) box_: syn::Path, pub(crate) compile_error: syn::Path, pub(crate) context_error: syn::Path, - pub(crate) core_type_of: syn::Path, pub(crate) double_ended_iterator: syn::Path, pub(crate) from_value: syn::Path, pub(crate) hash: syn::Path, @@ -748,6 +745,7 @@ pub(crate) struct Tokens { pub(crate) try_clone: syn::Path, pub(crate) try_from: syn::Path, pub(crate) tuple: syn::Path, + pub(crate) type_hash_t: syn::Path, pub(crate) type_info: syn::Path, pub(crate) type_name: syn::Path, pub(crate) type_of: syn::Path, diff --git a/crates/rune-macros/src/function.rs b/crates/rune-macros/src/function.rs index 15d29dfba..60225c322 100644 --- a/crates/rune-macros/src/function.rs +++ b/crates/rune-macros/src/function.rs @@ -289,7 +289,7 @@ impl Function { for argument in arguments { array.elems.push(syn::Expr::Verbatim(quote! { - <#argument as rune::__private::CoreTypeOf>::type_hash() + <#argument as rune::__private::TypeHash>::HASH })); } diff --git a/crates/rune-shim/src/lib.rs b/crates/rune-shim/src/lib.rs index 59653670e..165ddc32c 100644 --- a/crates/rune-shim/src/lib.rs +++ b/crates/rune-shim/src/lib.rs @@ -1,15 +1,43 @@ +//! This crate is only used to build documentation for the `rune-core` crate. + #[cfg(feature = "rune-alloc")] pub use rune_alloc as alloc; #[cfg(feature = "rune-core")] pub mod item { + #[doc(inline)] pub use rune_core::item::{Component, ComponentRef, IntoComponent, Item, ItemBuf}; } +#[cfg(feature = "rune-core")] +pub mod hash { + #[doc(inline)] + pub use rune_core::hash::{ParametersBuilder, TooManyParameters}; +} + pub mod support { pub use anyhow::Error; pub use anyhow::Result; } +pub mod runtime { + use rune_core::hash::Hash; + + pub trait TypeHash { + const HASH: Hash; + } + + impl TypeHash for String { + const HASH: Hash = Hash::new(1); + } + + impl TypeHash for i64 { + const HASH: Hash = Hash::new(2); + } +} + +#[cfg(feature = "rune-core")] +pub use self::runtime::TypeHash; + #[cfg(feature = "rune-core")] pub use rune_core::item::{Item, ItemBuf}; diff --git a/crates/rune/src/any.rs b/crates/rune/src/any.rs index 350a90f48..a742f6fd3 100644 --- a/crates/rune/src/any.rs +++ b/crates/rune/src/any.rs @@ -1,7 +1,7 @@ use core::any; use crate::compile::Named; -use crate::runtime::CoreTypeOf; +use crate::runtime::{AnyTypeInfo, TypeHash}; /// Macro to mark a value as external, which will implement all the appropriate /// traits. @@ -110,7 +110,10 @@ pub use rune_macros::Any; /// Ok(module) /// } /// ``` -pub trait Any: CoreTypeOf + Named + any::Any {} +pub trait Any: TypeHash + Named + any::Any { + /// The compile-time type information know for the type. + const INFO: AnyTypeInfo = AnyTypeInfo::new(Self::BASE_NAME, Self::HASH); +} // Internal any impls for useful types in the std library. diff --git a/crates/rune/src/cli/mod.rs b/crates/rune/src/cli/mod.rs index 36374219c..3ed7feefb 100644 --- a/crates/rune/src/cli/mod.rs +++ b/crates/rune/src/cli/mod.rs @@ -376,6 +376,9 @@ struct HashFlags { /// Generate a random hash. #[arg(long)] random: bool, + /// When generating a random hash, generate the given number of hashes. + #[arg(long)] + count: Option, /// Items to generate hashes for. item: Vec, } @@ -1039,8 +1042,10 @@ where use rand::prelude::*; if args.random { - let mut rand = rand::thread_rng(); - writeln!(io.stdout, "{}", Hash::new(rand.gen::()))?; + for _ in 0..args.count.unwrap_or(1) { + let mut rand = rand::thread_rng(); + writeln!(io.stdout, "{}", Hash::new(rand.gen::()))?; + } } for item in &args.item { diff --git a/crates/rune/src/compile/context.rs b/crates/rune/src/compile/context.rs index 4912f1ee5..80175768f 100644 --- a/crates/rune/src/compile/context.rs +++ b/crates/rune/src/compile/context.rs @@ -724,7 +724,7 @@ impl Context { item: item.try_clone()?, hash, type_check: None, - type_info: TypeInfo::Variant(Arc::new(VariantRtti { + type_info: TypeInfo::variant(Arc::new(VariantRtti { enum_hash: ty.hash, hash, item: item.try_clone()?, diff --git a/crates/rune/src/compile/error.rs b/crates/rune/src/compile/error.rs index 56715fdd2..802d7d963 100644 --- a/crates/rune/src/compile/error.rs +++ b/crates/rune/src/compile/error.rs @@ -14,6 +14,7 @@ use crate::ast::unescape; use crate::ast::{Span, Spanned}; use crate::compile::ir; use crate::compile::{HasSpan, Location, MetaInfo, Visibility}; +use crate::hash::TooManyParameters; use crate::indexing::items::{GuardMismatch, MissingLastId}; use crate::macros::{SyntheticId, SyntheticKind}; use crate::parse::{Expectation, IntoExpectation, LexerMode}; @@ -108,6 +109,13 @@ where } } +impl From for ErrorKind { + #[inline] + fn from(error: TooManyParameters) -> Self { + ErrorKind::TooManyParameters(error) + } +} + impl From for ErrorKind { #[inline] fn from(fmt::Error: fmt::Error) -> Self { @@ -254,6 +262,7 @@ pub(crate) enum ErrorKind { PopError(PopError), UnescapeError(unescape::ErrorKind), Syntree(syntree::Error), + TooManyParameters(TooManyParameters), FormatError, #[cfg(feature = "std")] SourceError { @@ -672,6 +681,9 @@ impl fmt::Display for ErrorKind { ErrorKind::Syntree(error) => { error.fmt(f)?; } + ErrorKind::TooManyParameters(error) => { + error.fmt(f)?; + } ErrorKind::FormatError => { write!(f, "Formatting error")?; } diff --git a/crates/rune/src/function/mod.rs b/crates/rune/src/function/mod.rs index 7efecf642..109349094 100644 --- a/crates/rune/src/function/mod.rs +++ b/crates/rune/src/function/mod.rs @@ -8,8 +8,8 @@ use crate::alloc; use crate::compile::meta; use crate::hash::Hash; use crate::runtime::{ - self, CoreTypeOf, FromValue, InstAddress, MaybeTypeOf, Memory, Output, ToValue, TypeInfo, - TypeOf, UnsafeToMut, UnsafeToRef, Value, VmErrorKind, VmResult, + self, FromValue, InstAddress, MaybeTypeOf, Memory, Output, ToValue, TypeHash, TypeInfo, TypeOf, + UnsafeToMut, UnsafeToRef, Value, VmErrorKind, VmResult, }; // Expand to function variable bindings. @@ -158,24 +158,18 @@ where } } -impl CoreTypeOf for Ref +impl TypeHash for Ref where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } impl TypeOf for Ref where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { @@ -196,24 +190,18 @@ where } } -impl CoreTypeOf for Mut +impl TypeHash for Mut where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } impl TypeOf for Mut where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { diff --git a/crates/rune/src/function_meta.rs b/crates/rune/src/function_meta.rs index ce4074acb..ef8b93d2c 100644 --- a/crates/rune/src/function_meta.rs +++ b/crates/rune/src/function_meta.rs @@ -244,7 +244,7 @@ impl Associated { { Ok(Self { name, - container: T::type_hash(), + container: T::HASH, container_type_info: T::type_info(), }) } diff --git a/crates/rune/src/hash.rs b/crates/rune/src/hash.rs index 347ae2e75..f23247129 100644 --- a/crates/rune/src/hash.rs +++ b/crates/rune/src/hash.rs @@ -1,3 +1,5 @@ +//! Utilities for working with hashes. + use crate::alloc::HashMap; use core::hash::{BuildHasher, Hasher}; @@ -5,9 +7,7 @@ use core::hash::{BuildHasher, Hasher}; const SEED: u64 = 18446744073709551557u64; #[doc(inline)] -pub use rune_core::hash::{Hash, ToTypeHash}; -#[doc(inline)] -pub(crate) use rune_core::hash::{IntoHash, ParametersBuilder}; +pub use rune_core::hash::{Hash, IntoHash, ParametersBuilder, ToTypeHash, TooManyParameters}; /// A hash map suitable for storing values with hash keys. pub(crate) type Map = HashMap; diff --git a/crates/rune/src/hir/lowering.rs b/crates/rune/src/hir/lowering.rs index 9d6030522..39ad13463 100644 --- a/crates/rune/src/hir/lowering.rs +++ b/crates/rune/src/hir/lowering.rs @@ -1664,7 +1664,7 @@ fn generics_parameters( .iter() .zip(parameters.parameters.iter_mut()) { - if let &Some((_, generics)) = value { + if let &Some((span, generics)) = value { let mut builder = ParametersBuilder::new(); for (s, _) in generics { @@ -1672,7 +1672,7 @@ fn generics_parameters( return Err(compile::Error::new(s, ErrorKind::UnsupportedGenerics)); }; - builder.add(ty.into_hash()); + builder = builder.add(ty.into_hash()).with_span(span)?; } *o = Some(builder.finish()); @@ -1872,7 +1872,7 @@ fn expr_field_access<'hir>( return Err(compile::Error::new(s, ErrorKind::UnsupportedGenerics)); }; - builder.add(ty.into_hash()); + builder = builder.add(ty.into_hash()).with_span(s)?; } hir::ExprField::IdentGenerics(ident, builder.finish()) diff --git a/crates/rune/src/hir/lowering2.rs b/crates/rune/src/hir/lowering2.rs index 31f17e8e1..f0c7c2583 100644 --- a/crates/rune/src/hir/lowering2.rs +++ b/crates/rune/src/hir/lowering2.rs @@ -2530,7 +2530,7 @@ fn generic_arguments(cx: &mut Ctxt<'_, '_, '_>, p: &mut Stream<'_>) -> Result $ty:ty => $static_type:expr) => { - impl<$($p,)*> $crate::runtime::CoreTypeOf for $ty { - #[inline] - fn type_hash() -> $crate::Hash { - $static_type.hash - } + (impl <$($p:ident),*> $ty:ty, $static_type:expr, $static_type_hash:expr) => { + impl<$($p,)*> $crate::TypeHash for $ty { + const HASH: $crate::Hash = $static_type_hash; } impl<$($p,)*> $crate::runtime::TypeOf for $ty @@ -24,7 +21,7 @@ macro_rules! impl_static_type { { #[inline] fn type_info() -> $crate::runtime::TypeInfo { - $crate::runtime::TypeInfo::StaticType($static_type) + $crate::runtime::TypeInfo::static_type($static_type) } } @@ -35,15 +32,15 @@ macro_rules! impl_static_type { #[inline] fn maybe_type_of() -> $crate::alloc::Result<$crate::compile::meta::DocType> { $crate::compile::meta::DocType::with_generics( - <$ty as $crate::runtime::CoreTypeOf>::type_hash(), + <$ty as $crate::TypeHash>::HASH, [$(<$p as $crate::runtime::MaybeTypeOf>::maybe_type_of()?),*] ) } } }; - ($ty:ty => $static_type:expr) => { - impl_static_type!(impl <> $ty => $static_type); + ($ty:ty, $static_type:expr, $static_type_hash:expr) => { + impl_static_type!(impl <> $ty, $static_type, $static_type_hash); }; } diff --git a/crates/rune/src/lib.rs b/crates/rune/src/lib.rs index cc2956257..967260f85 100644 --- a/crates/rune/src/lib.rs +++ b/crates/rune/src/lib.rs @@ -228,7 +228,8 @@ pub mod diagnostics; #[doc(inline)] pub use self::diagnostics::Diagnostics; -mod hash; +pub mod hash; +#[doc(inline)] pub use self::hash::{Hash, ToTypeHash}; #[cfg(feature = "alloc")] @@ -253,7 +254,7 @@ pub mod query; pub mod runtime; #[doc(inline)] -pub use self::runtime::{from_value, to_value, FromValue, ToValue, Unit, Value, Vm}; +pub use self::runtime::{from_value, to_value, FromValue, ToValue, TypeHash, Unit, Value, Vm}; mod shared; @@ -666,7 +667,7 @@ pub mod __private { pub use crate::item::ItemBuf; pub use crate::module::{InstallWith, Module, ModuleMetaData}; pub use crate::params::Params; - pub use crate::runtime::{CoreTypeOf, TypeOf}; + pub use crate::runtime::{TypeHash, TypeOf}; pub use rust_alloc::boxed::Box; } diff --git a/crates/rune/src/module/module.rs b/crates/rune/src/module/module.rs index 84c22ef06..9368d918e 100644 --- a/crates/rune/src/module/module.rs +++ b/crates/rune/src/module/module.rs @@ -191,8 +191,8 @@ impl Module { T: ?Sized + TypeOf + Named + InstallWith, { let item = ItemBuf::with_item([T::BASE_NAME])?; - let hash = T::type_hash(); - let type_parameters = T::type_parameters(); + let hash = T::HASH; + let type_parameters = T::PARAMETERS; let type_info = T::type_info(); if !self.names.try_insert(Name::Item(hash))? { @@ -239,7 +239,7 @@ impl Module { where T: ?Sized + TypeOf + Named, { - let type_hash = T::type_hash(); + let type_hash = T::HASH; let Some(ty) = self.types_hash.get(&type_hash).map(|&i| &mut self.types[i]) else { let full_name = String::try_from(T::full_name())?; @@ -295,7 +295,7 @@ impl Module { where T: ?Sized + TypeOf + Named, { - let type_hash = T::type_hash(); + let type_hash = T::HASH; let Some(ty) = self.types_hash.get(&type_hash).map(|&i| &mut self.types[i]) else { let full_name = String::try_from(T::full_name())?; @@ -1561,7 +1561,7 @@ impl Module { T: ?Sized + TypeOf + Named, { let item = ItemBuf::with_item([T::BASE_NAME])?; - let hash = T::type_hash(); + let hash = T::HASH; let type_info = T::type_info(); let trait_hash = Hash::type_hash(trait_item); diff --git a/crates/rune/src/modules/collections/vec_deque.rs b/crates/rune/src/modules/collections/vec_deque.rs index d74c5aa50..7ab8e5a4f 100644 --- a/crates/rune/src/modules/collections/vec_deque.rs +++ b/crates/rune/src/modules/collections/vec_deque.rs @@ -502,7 +502,7 @@ impl VecDeque { fn iter(this: Ref) -> Iter { // SAFETY: We're holding onto the reference guard. let iter = unsafe { this.inner.raw_iter() }; - let (_, _guard) = Ref::into_raw(this); + let (_, guard) = Ref::into_raw(this); Iter { iter, guard } } diff --git a/crates/rune/src/modules/iter.rs b/crates/rune/src/modules/iter.rs index b491e3c9a..675e25621 100644 --- a/crates/rune/src/modules/iter.rs +++ b/crates/rune/src/modules/iter.rs @@ -8,8 +8,8 @@ use crate::modules::collections::VecDeque; use crate::modules::collections::{HashMap, HashSet}; use crate::runtime::range::RangeIter; use crate::runtime::{ - CoreTypeOf, FromValue, Function, Inline, InstAddress, Mutable, Object, Output, OwnedTuple, - Protocol, Value, ValueBorrowRef, Vec, VmErrorKind, VmResult, + FromValue, Function, Inline, InstAddress, Mutable, Object, Output, OwnedTuple, Protocol, + TypeHash, Value, ValueBorrowRef, Vec, VmErrorKind, VmResult, }; use crate::shared::Caller; use crate::{Any, ContextError, Module, Params}; @@ -369,19 +369,16 @@ pub fn module() -> Result { let next = next.clone(); let size_hint = size_hint.clone(); - cx.function( - Params::new("collect", [Vec::type_hash()]), - move |iter: Value| { - let (cap, _) = vm_try!(size_hint.call((&iter,))); - let mut vec = vm_try!(Vec::with_capacity(cap)); + cx.function(Params::new("collect", [Vec::HASH]), move |iter: Value| { + let (cap, _) = vm_try!(size_hint.call((&iter,))); + let mut vec = vm_try!(Vec::with_capacity(cap)); - while let Some(value) = vm_try!(next.call((&iter,))) { - vm_try!(vec.push(value)); - } + while let Some(value) = vm_try!(next.call((&iter,))) { + vm_try!(vec.push(value)); + } - VmResult::Ok(vec) - }, - )?; + VmResult::Ok(vec) + })?; } { @@ -389,7 +386,7 @@ pub fn module() -> Result { let size_hint = size_hint.clone(); cx.function( - Params::new("collect", [VecDeque::type_hash()]), + Params::new("collect", [VecDeque::HASH]), move |iter: Value| { let (cap, _) = vm_try!(size_hint.call((&iter,))); let mut vec = vm_try!(Vec::with_capacity(cap)); @@ -408,7 +405,7 @@ pub fn module() -> Result { let size_hint = size_hint.clone(); cx.function( - Params::new("collect", [HashSet::type_hash()]), + Params::new("collect", [HashSet::HASH]), move |iter: Value| { let (cap, _) = vm_try!(size_hint.call((&iter,))); let mut set = vm_try!(HashSet::with_capacity(cap)); @@ -427,7 +424,7 @@ pub fn module() -> Result { let size_hint = size_hint.clone(); cx.function( - Params::new("collect", [HashMap::type_hash()]), + Params::new("collect", [HashMap::HASH]), move |iter: Value| { let (cap, _) = vm_try!(size_hint.call((&iter,))); let mut map = vm_try!(HashMap::with_capacity(cap)); @@ -446,7 +443,7 @@ pub fn module() -> Result { let size_hint = size_hint.clone(); cx.function( - Params::new("collect", [Object::type_hash()]), + Params::new("collect", [Object::HASH]), move |iter: Value| { let (cap, _) = vm_try!(size_hint.call((&iter,))); let mut map = vm_try!(Object::with_capacity(cap)); @@ -465,7 +462,7 @@ pub fn module() -> Result { let size_hint = size_hint.clone(); cx.function( - Params::new("collect", [OwnedTuple::type_hash()]), + Params::new("collect", [OwnedTuple::HASH]), move |iter: Value| { let (cap, _) = vm_try!(size_hint.call((&iter,))); let mut vec = vm_try!(alloc::Vec::try_with_capacity(cap)); @@ -483,7 +480,7 @@ pub fn module() -> Result { let next = next.clone(); cx.function( - Params::new("collect", [String::type_hash()]), + Params::new("collect", [String::HASH]), move |iter: Value| { let mut string = String::new(); @@ -513,31 +510,28 @@ pub fn module() -> Result { macro_rules! ops { ($ty:ty) => {{ - cx.function( - Params::new("product", [<$ty>::type_hash()]), - |iter: Value| { - let mut product = match vm_try!(iter.protocol_next()) { - Some(init) => vm_try!(<$ty>::from_value(init)), - None => <$ty>::ONE, - }; + cx.function(Params::new("product", [<$ty>::HASH]), |iter: Value| { + let mut product = match vm_try!(iter.protocol_next()) { + Some(init) => vm_try!(<$ty>::from_value(init)), + None => <$ty>::ONE, + }; - while let Some(v) = vm_try!(iter.protocol_next()) { - let v = vm_try!(<$ty>::from_value(v)); + while let Some(v) = vm_try!(iter.protocol_next()) { + let v = vm_try!(<$ty>::from_value(v)); - let Some(out) = product.checked_mul(v) else { - return VmResult::err(VmErrorKind::Overflow); - }; + let Some(out) = product.checked_mul(v) else { + return VmResult::err(VmErrorKind::Overflow); + }; - product = out; - } + product = out; + } - VmResult::Ok(product) - }, - )?; + VmResult::Ok(product) + })?; } { - cx.function(Params::new("sum", [<$ty>::type_hash()]), |iter: Value| { + cx.function(Params::new("sum", [<$ty>::HASH]), |iter: Value| { let mut sum = match vm_try!(iter.protocol_next()) { Some(init) => vm_try!(<$ty>::from_value(init)), None => <$ty>::ZERO, @@ -1370,7 +1364,7 @@ pub fn module() -> Result { macro_rules! sum_ops { ($ty:ty) => { - t.function(Params::new("sum", [<$ty>::type_hash()]))? + t.function(Params::new("sum", [<$ty>::HASH]))? .argument_types::<(Value,)>()? .return_type::<$ty>()? .docs(docstring! { @@ -1409,7 +1403,7 @@ pub fn module() -> Result { macro_rules! integer_product_ops { ($ty:ty) => { - t.function(Params::new("product", [<$ty>::type_hash()]))? + t.function(Params::new("product", [<$ty>::HASH]))? .argument_types::<(Value,)>()? .return_type::<$ty>()? .docs(docstring! { @@ -1441,7 +1435,7 @@ pub fn module() -> Result { }; } - t.function(Params::new("collect", [Vec::type_hash()]))? + t.function(Params::new("collect", [Vec::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`Vec`]. @@ -1455,7 +1449,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [VecDeque::type_hash()]))? + t.function(Params::new("collect", [VecDeque::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`VecDeque`]. @@ -1469,7 +1463,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [HashSet::type_hash()]))? + t.function(Params::new("collect", [HashSet::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`HashSet`]. @@ -1486,7 +1480,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [HashMap::type_hash()]))? + t.function(Params::new("collect", [HashMap::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`HashMap`]. @@ -1508,7 +1502,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [Object::type_hash()]))? + t.function(Params::new("collect", [Object::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as an [`Object`]. @@ -1520,7 +1514,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [OwnedTuple::type_hash()]))? + t.function(Params::new("collect", [OwnedTuple::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`Tuple`]. @@ -1532,7 +1526,7 @@ pub fn module() -> Result { /// ``` })?; - t.function(Params::new("collect", [String::type_hash()]))? + t.function(Params::new("collect", [String::HASH]))? .return_type::()? .docs(docstring! { /// Collect the iterator as a [`String`]. @@ -1546,7 +1540,7 @@ pub fn module() -> Result { macro_rules! float_product_ops { ($ty:ty) => { - t.function(Params::new("product", [<$ty>::type_hash()]))? + t.function(Params::new("product", [<$ty>::HASH]))? .argument_types::<(Value,)>()? .return_type::<$ty>()? .docs(docstring! { diff --git a/crates/rune/src/params.rs b/crates/rune/src/params.rs index 9ed9d5471..fcdb8d175 100644 --- a/crates/rune/src/params.rs +++ b/crates/rune/src/params.rs @@ -18,7 +18,7 @@ where Ok(AssociatedName { kind: info.kind, - function_parameters: Hash::parameters(self.parameters.iter().copied()), + function_parameters: Hash::parameters(self.parameters), #[cfg(feature = "doc")] parameter_types: self.parameters.iter().copied().try_collect()?, }) @@ -35,7 +35,7 @@ where Ok(AssociatedName { kind: info.kind, - function_parameters: Hash::parameters(self.parameters.iter().copied()), + function_parameters: Hash::parameters(self.parameters), #[cfg(feature = "doc")] parameter_types: self.parameters.iter().copied().try_collect()?, }) diff --git a/crates/rune/src/runtime/any_obj.rs b/crates/rune/src/runtime/any_obj.rs index da5d09292..d9ee46d87 100644 --- a/crates/rune/src/runtime/any_obj.rs +++ b/crates/rune/src/runtime/any_obj.rs @@ -9,8 +9,8 @@ use crate::alloc::{self, Box}; use crate::{Any, Hash}; use super::{ - Access, AccessError, AnyTypeInfo, BorrowMut, BorrowRef, Mut, RawAccessGuard, RawAnyGuard, - RawStr, Ref, RefVtable, Snapshot, TypeInfo, VmErrorKind, + Access, AccessError, AnyTypeInfo, BorrowMut, BorrowRef, Mut, RawAccessGuard, RawAnyGuard, Ref, + RefVtable, Snapshot, TypeInfo, VmErrorKind, }; /// Errors caused by casting an any reference. @@ -82,8 +82,8 @@ impl AnyObj { kind: Kind::Own, type_id: TypeId::of::, debug: debug_ref_impl::, - type_name: type_name_impl::, - type_hash: T::type_hash, + type_info: T::INFO, + type_hash: T::HASH, drop_value: const { if needs_drop::() { Some(drop_value::) @@ -120,8 +120,8 @@ impl AnyObj { kind: Kind::Ref, type_id: TypeId::of::, debug: debug_ref_impl::, - type_name: type_name_impl::, - type_hash: T::type_hash, + type_info: T::INFO, + type_hash: T::HASH, drop_value: None, drop: drop_box::>, clone: clone_ref::, @@ -152,8 +152,8 @@ impl AnyObj { kind: Kind::Mut, type_id: TypeId::of::, debug: debug_mut_impl::, - type_name: type_name_impl::, - type_hash: T::type_hash, + type_info: T::INFO, + type_hash: T::HASH, drop_value: None, drop: drop_box::>, clone: clone_mut::, @@ -273,12 +273,12 @@ impl AnyObj { } } - /// Downcast into an owned value of type [`Ref`]. + /// Downcast into an owned value of type [`Mut`]. /// /// # Errors /// /// This errors in case the underlying value is not owned, non-owned - /// references cannot be coerced into [`Ref`]. + /// references cannot be coerced into [`Mut`]. pub(crate) fn downcast_mut(self) -> Result, AnyObjError> where T: Any, @@ -472,12 +472,12 @@ impl AnyObj { /// Access the underlying type id for the data. pub(crate) fn type_hash(&self) -> Hash { - (vtable(self).type_hash)() + vtable(self).type_hash } /// Access full type info for type. pub(crate) fn type_info(&self) -> TypeInfo { - unsafe { self.shared.as_ref().type_info() } + TypeInfo::any_type_info(vtable(self).type_info) } } @@ -531,12 +531,6 @@ type TypeIdFn = fn() -> TypeId; /// The signature of a descriptive type name function. type DebugFn = fn(&mut fmt::Formatter<'_>) -> fmt::Result; -/// Get the type name. -type TypeNameFn = fn() -> RawStr; - -/// The signature of a type hash function. -type TypeHashFn = fn() -> Hash; - /// The kind of the stored value in the `AnyObj`. enum Kind { /// Underlying access is shared. @@ -554,10 +548,10 @@ struct Vtable { type_id: TypeIdFn, /// Type information for diagnostics. debug: DebugFn, - /// Type name accessor. - type_name: TypeNameFn, - /// Get the type hash of the stored type. - type_hash: TypeHashFn, + /// Type information. + type_info: AnyTypeInfo, + /// Type hash of the interior type. + type_hash: Hash, /// Value drop implementation. Set to `None` if the underlying value does /// not need to be dropped. drop_value: Option)>, @@ -568,6 +562,11 @@ struct Vtable { } impl Vtable { + #[inline] + fn type_info(&self) -> TypeInfo { + TypeInfo::any_type_info(self.type_info) + } + fn as_ptr(&self, base: NonNull) -> NonNull { if matches!(self.kind, Kind::Own) { unsafe { base.byte_add(offset_of!(Shared, data)).cast() } @@ -579,14 +578,6 @@ impl Vtable { } } } - - /// Construct type information. - fn type_info(&self) -> TypeInfo { - TypeInfo::Any(AnyTypeInfo::__private_new( - (self.type_name)(), - (self.type_hash)(), - )) - } } #[repr(C)] @@ -602,11 +593,6 @@ struct Shared { } impl Shared { - /// Construct type information. - fn type_info(&self) -> TypeInfo { - self.vtable.type_info() - } - /// Increment the reference count of the inner value. unsafe fn inc(this: NonNull) { let count_ref = &*addr_of!((*this.as_ptr()).count); @@ -672,13 +658,6 @@ where write!(f, "&mut {}", T::BASE_NAME) } -fn type_name_impl() -> RawStr -where - T: ?Sized + Any, -{ - T::BASE_NAME -} - unsafe fn drop_value(this: NonNull) { let data = addr_of_mut!((*this.cast::>().as_ptr()).data); drop_in_place(data); diff --git a/crates/rune/src/runtime/const_value.rs b/crates/rune/src/runtime/const_value.rs index 94a3e4eaf..cf72c8b66 100644 --- a/crates/rune/src/runtime/const_value.rs +++ b/crates/rune/src/runtime/const_value.rs @@ -165,18 +165,18 @@ impl ConstValue { /// Get the type information of the value. pub fn type_info(&self) -> TypeInfo { match self { - Self::Unit => TypeInfo::StaticType(crate::runtime::static_type::TUPLE), - Self::Byte(..) => TypeInfo::StaticType(crate::runtime::static_type::BYTE), - Self::Char(..) => TypeInfo::StaticType(crate::runtime::static_type::CHAR), - Self::Bool(..) => TypeInfo::StaticType(crate::runtime::static_type::BOOL), - Self::String(..) => TypeInfo::StaticType(crate::runtime::static_type::STRING), - Self::Bytes(..) => TypeInfo::StaticType(crate::runtime::static_type::BYTES), - Self::Integer(..) => TypeInfo::StaticType(crate::runtime::static_type::INTEGER), - Self::Float(..) => TypeInfo::StaticType(crate::runtime::static_type::FLOAT), - Self::Vec(..) => TypeInfo::StaticType(crate::runtime::static_type::VEC), - Self::Tuple(..) => TypeInfo::StaticType(crate::runtime::static_type::TUPLE), - Self::Object(..) => TypeInfo::StaticType(crate::runtime::static_type::OBJECT), - Self::Option(..) => TypeInfo::StaticType(crate::runtime::static_type::OPTION), + Self::Unit => TypeInfo::static_type(crate::runtime::static_type::TUPLE), + Self::Byte(..) => TypeInfo::static_type(crate::runtime::static_type::BYTE), + Self::Char(..) => TypeInfo::static_type(crate::runtime::static_type::CHAR), + Self::Bool(..) => TypeInfo::static_type(crate::runtime::static_type::BOOL), + Self::String(..) => TypeInfo::static_type(crate::runtime::static_type::STRING), + Self::Bytes(..) => TypeInfo::static_type(crate::runtime::static_type::BYTES), + Self::Integer(..) => TypeInfo::static_type(crate::runtime::static_type::INTEGER), + Self::Float(..) => TypeInfo::static_type(crate::runtime::static_type::FLOAT), + Self::Vec(..) => TypeInfo::static_type(crate::runtime::static_type::VEC), + Self::Tuple(..) => TypeInfo::static_type(crate::runtime::static_type::TUPLE), + Self::Object(..) => TypeInfo::static_type(crate::runtime::static_type::OBJECT), + Self::Option(..) => TypeInfo::static_type(crate::runtime::static_type::OPTION), } } } diff --git a/crates/rune/src/runtime/mod.rs b/crates/rune/src/runtime/mod.rs index d83f576c9..352fbf82f 100644 --- a/crates/rune/src/runtime/mod.rs +++ b/crates/rune/src/runtime/mod.rs @@ -157,7 +157,7 @@ mod type_info; pub use self::type_info::{AnyTypeInfo, TypeInfo}; mod type_of; -pub use self::type_of::{CoreTypeOf, MaybeTypeOf, TypeOf}; +pub use self::type_of::{MaybeTypeOf, TypeHash, TypeOf}; pub mod unit; pub(crate) use self::unit::UnitFn; diff --git a/crates/rune/src/runtime/object.rs b/crates/rune/src/runtime/object.rs index a3362e085..a76a065bb 100644 --- a/crates/rune/src/runtime/object.rs +++ b/crates/rune/src/runtime/object.rs @@ -309,7 +309,7 @@ impl Object { // SAFETY: we're holding onto the related reference guard, and making // sure that it's dropped after the iterator. let iter = unsafe { this.inner.raw_table().iter() }; - let (_, _guard) = Ref::into_raw(this); + let (_, guard) = Ref::into_raw(this); RuneIter { iter, guard } } @@ -333,7 +333,7 @@ impl Object { // SAFETY: we're holding onto the related reference guard, and making // sure that it's dropped after the iterator. let iter = unsafe { this.inner.raw_table().iter() }; - let (_, _guard) = Ref::into_raw(this); + let (_, guard) = Ref::into_raw(this); RuneIterKeys { iter, guard } } @@ -357,7 +357,7 @@ impl Object { // SAFETY: we're holding onto the related reference guard, and making // sure that it's dropped after the iterator. let iter = unsafe { this.inner.raw_table().iter() }; - let (_, _guard) = Ref::into_raw(this); + let (_, guard) = Ref::into_raw(this); RuneValues { iter, guard } } diff --git a/crates/rune/src/runtime/static_type.rs b/crates/rune/src/runtime/static_type.rs index 5e94db035..83b1b6b06 100644 --- a/crates/rune/src/runtime/static_type.rs +++ b/crates/rune/src/runtime/static_type.rs @@ -22,7 +22,7 @@ pub struct StaticType { impl StaticType { #[inline] pub(crate) fn type_info(&'static self) -> TypeInfo { - TypeInfo::StaticType(self) + TypeInfo::static_type(self) } } @@ -55,23 +55,27 @@ pub(crate) static BYTE: &StaticType = &StaticType { hash: BYTE_HASH, }; -impl_static_type!(u8 => BYTE); +impl_static_type!(u8, BYTE, BYTE_HASH); + +pub(crate) const BOOL_HASH: Hash = ::rune_macros::hash!(::std::bool); /// The specialized type information for a bool type. pub(crate) static BOOL: &StaticType = &StaticType { name: RawStr::from_str("bool"), - hash: ::rune_macros::hash!(::std::bool), + hash: BOOL_HASH, }; -impl_static_type!(bool => BOOL); +impl_static_type!(bool, BOOL, BOOL_HASH); + +pub(crate) const CHAR_HASH: Hash = ::rune_macros::hash!(::std::char); /// The specialized type information for a char type. pub(crate) static CHAR: &StaticType = &StaticType { name: RawStr::from_str("char"), - hash: ::rune_macros::hash!(::std::char), + hash: CHAR_HASH, }; -impl_static_type!(char => CHAR); +impl_static_type!(char, CHAR, CHAR_HASH); /// Hash for `::std::i64`. pub(crate) const INTEGER_HASH: Hash = ::rune_macros::hash!(::std::i64); @@ -82,18 +86,18 @@ pub(crate) static INTEGER: &StaticType = &StaticType { hash: INTEGER_HASH, }; -impl_static_type!(i8 => INTEGER); +impl_static_type!(i8, INTEGER, INTEGER_HASH); // NB: u8 is its own type BYTE. -impl_static_type!(u16 => INTEGER); -impl_static_type!(i16 => INTEGER); -impl_static_type!(u32 => INTEGER); -impl_static_type!(i32 => INTEGER); -impl_static_type!(u64 => INTEGER); -impl_static_type!(i64 => INTEGER); -impl_static_type!(u128 => INTEGER); -impl_static_type!(i128 => INTEGER); -impl_static_type!(usize => INTEGER); -impl_static_type!(isize => INTEGER); +impl_static_type!(u16, INTEGER, INTEGER_HASH); +impl_static_type!(i16, INTEGER, INTEGER_HASH); +impl_static_type!(u32, INTEGER, INTEGER_HASH); +impl_static_type!(i32, INTEGER, INTEGER_HASH); +impl_static_type!(u64, INTEGER, INTEGER_HASH); +impl_static_type!(i64, INTEGER, INTEGER_HASH); +impl_static_type!(u128, INTEGER, INTEGER_HASH); +impl_static_type!(i128, INTEGER, INTEGER_HASH); +impl_static_type!(usize, INTEGER, INTEGER_HASH); +impl_static_type!(isize, INTEGER, INTEGER_HASH); /// Hash for `::std::f64`. pub(crate) const FLOAT_HASH: Hash = ::rune_macros::hash!(::std::f64); @@ -103,150 +107,186 @@ pub(crate) static FLOAT: &StaticType = &StaticType { hash: FLOAT_HASH, }; -impl_static_type!(f32 => FLOAT); -impl_static_type!(f64 => FLOAT); +impl_static_type!(f32, FLOAT, FLOAT_HASH); +impl_static_type!(f64, FLOAT, FLOAT_HASH); +pub(crate) const STRING_HASH: Hash = ::rune_macros::hash!(::std::string::String); pub(crate) static STRING: &StaticType = &StaticType { name: RawStr::from_str("String"), - hash: ::rune_macros::hash!(::std::string::String), + hash: STRING_HASH, }; #[cfg(feature = "alloc")] -impl_static_type!(::rust_alloc::string::String => STRING); -impl_static_type!(alloc::String => STRING); -impl_static_type!(alloc::Box => STRING); -impl_static_type!(str => STRING); +impl_static_type!(::rust_alloc::string::String, STRING, STRING_HASH); +impl_static_type!(alloc::String, STRING, STRING_HASH); +impl_static_type!(alloc::Box, STRING, STRING_HASH); +impl_static_type!(str, STRING, STRING_HASH); + +pub(crate) const BYTES_HASH: Hash = ::rune_macros::hash!(::std::bytes::Bytes); pub(crate) static BYTES: &StaticType = &StaticType { name: RawStr::from_str("Bytes"), - hash: ::rune_macros::hash!(::std::bytes::Bytes), + hash: BYTES_HASH, }; -impl_static_type!([u8] => BYTES); +impl_static_type!([u8], BYTES, BYTES_HASH); + +pub(crate) const VEC_HASH: Hash = ::rune_macros::hash!(::std::vec::Vec); pub(crate) static VEC: &StaticType = &StaticType { name: RawStr::from_str("Vec"), - hash: ::rune_macros::hash!(::std::vec::Vec), + hash: VEC_HASH, }; -impl_static_type!([rt::Value] => VEC); +impl_static_type!([rt::Value], VEC, VEC_HASH); #[cfg(feature = "alloc")] -impl_static_type!(impl ::rust_alloc::vec::Vec => VEC); -impl_static_type!(impl alloc::Vec => VEC); -impl_static_type!(impl rt::VecTuple => VEC); +impl_static_type!(impl ::rust_alloc::vec::Vec, VEC, VEC_HASH); +impl_static_type!(impl alloc::Vec, VEC, VEC_HASH); +impl_static_type!(impl rt::VecTuple, VEC, VEC_HASH); + +pub(crate) const TUPLE_HASH: Hash = ::rune_macros::hash!(::std::tuple::Tuple); pub(crate) static TUPLE: &StaticType = &StaticType { name: RawStr::from_str("Tuple"), - hash: ::rune_macros::hash!(::std::tuple::Tuple), + hash: TUPLE_HASH, }; -impl_static_type!(rt::OwnedTuple => TUPLE); +impl_static_type!(rt::OwnedTuple, TUPLE, TUPLE_HASH); + +pub(crate) const OBJECT_HASH: Hash = ::rune_macros::hash!(::std::object::Object); pub(crate) static OBJECT: &StaticType = &StaticType { name: RawStr::from_str("Object"), - hash: ::rune_macros::hash!(::std::object::Object), + hash: OBJECT_HASH, }; -impl_static_type!(rt::Struct => OBJECT); -impl_static_type!(impl HashMap<::rust_alloc::string::String, T> => OBJECT); -impl_static_type!(impl HashMap => OBJECT); +impl_static_type!(rt::Struct, OBJECT, OBJECT_HASH); +impl_static_type!(impl HashMap<::rust_alloc::string::String, T>, OBJECT, OBJECT_HASH); +impl_static_type!(impl HashMap, OBJECT, OBJECT_HASH); cfg_std! { - impl_static_type!(impl ::std::collections::HashMap<::rust_alloc::string::String, T> => OBJECT); - impl_static_type!(impl ::std::collections::HashMap => OBJECT); + impl_static_type!(impl ::std::collections::HashMap<::rust_alloc::string::String, T>, OBJECT, OBJECT_HASH); + impl_static_type!(impl ::std::collections::HashMap, OBJECT, OBJECT_HASH); } +pub(crate) const RANGE_FROM_HASH: Hash = ::rune_macros::hash!(::std::ops::RangeFrom); + pub(crate) static RANGE_FROM: &StaticType = &StaticType { name: RawStr::from_str("RangeFrom"), - hash: ::rune_macros::hash!(::std::ops::RangeFrom), + hash: RANGE_FROM_HASH, }; +pub(crate) const RANGE_FULL_HASH: Hash = ::rune_macros::hash!(::std::ops::RangeFull); + pub(crate) static RANGE_FULL: &StaticType = &StaticType { name: RawStr::from_str("RangeFull"), - hash: ::rune_macros::hash!(::std::ops::RangeFull), + hash: RANGE_FULL_HASH, }; +pub(crate) const RANGE_INCLUSIVE_HASH: Hash = ::rune_macros::hash!(::std::ops::RangeInclusive); + pub(crate) static RANGE_INCLUSIVE: &StaticType = &StaticType { name: RawStr::from_str("RangeInclusive"), - hash: ::rune_macros::hash!(::std::ops::RangeInclusive), + hash: RANGE_INCLUSIVE_HASH, }; +pub(crate) const RANGE_TO_INCLUSIVE_HASH: Hash = ::rune_macros::hash!(::std::ops::RangeToInclusive); + pub(crate) static RANGE_TO_INCLUSIVE: &StaticType = &StaticType { name: RawStr::from_str("RangeToInclusive"), - hash: ::rune_macros::hash!(::std::ops::RangeToInclusive), + hash: RANGE_TO_INCLUSIVE_HASH, }; +pub(crate) const RANGE_TO_HASH: Hash = ::rune_macros::hash!(::std::ops::RangeTo); + pub(crate) static RANGE_TO: &StaticType = &StaticType { name: RawStr::from_str("RangeTo"), - hash: ::rune_macros::hash!(::std::ops::RangeTo), + hash: RANGE_TO_HASH, }; +pub(crate) const RANGE_HASH: Hash = ::rune_macros::hash!(::std::ops::Range); + pub(crate) static RANGE: &StaticType = &StaticType { name: RawStr::from_str("Range"), - hash: ::rune_macros::hash!(::std::ops::Range), + hash: RANGE_HASH, }; +pub(crate) const CONTROL_FLOW_HASH: Hash = ::rune_macros::hash!(::std::ops::ControlFlow); + pub(crate) static CONTROL_FLOW: &StaticType = &StaticType { name: RawStr::from_str("ControlFlow"), - hash: ::rune_macros::hash!(::std::ops::ControlFlow), + hash: CONTROL_FLOW_HASH, }; -impl_static_type!(impl ControlFlow => CONTROL_FLOW); +impl_static_type!(impl ControlFlow, CONTROL_FLOW, CONTROL_FLOW_HASH); +pub(crate) const FUTURE_HASH: Hash = ::rune_macros::hash!(::std::future::Future); pub(crate) static FUTURE: &StaticType = &StaticType { name: RawStr::from_str("Future"), - hash: ::rune_macros::hash!(::std::future::Future), + hash: FUTURE_HASH, }; +pub(crate) const GENERATOR_HASH: Hash = ::rune_macros::hash!(::std::ops::generator::Generator); pub(crate) static GENERATOR: &StaticType = &StaticType { name: RawStr::from_str("Generator"), - hash: ::rune_macros::hash!(::std::ops::generator::Generator), + hash: GENERATOR_HASH, }; +pub(crate) const GENERATOR_STATE_HASH: Hash = + ::rune_macros::hash!(::std::ops::generator::GeneratorState); pub(crate) static GENERATOR_STATE: &StaticType = &StaticType { name: RawStr::from_str("GeneratorState"), - hash: ::rune_macros::hash!(::std::ops::generator::GeneratorState), + hash: GENERATOR_STATE_HASH, }; +pub(crate) const STREAM_HASH: Hash = ::rune_macros::hash!(::std::stream::Stream); pub(crate) static STREAM: &StaticType = &StaticType { name: RawStr::from_str("Stream"), - hash: ::rune_macros::hash!(::std::stream::Stream), + hash: STREAM_HASH, }; +pub(crate) const RESULT_HASH: Hash = ::rune_macros::hash!(::std::result::Result); + pub(crate) static RESULT: &StaticType = &StaticType { name: RawStr::from_str("Result"), - hash: ::rune_macros::hash!(::std::result::Result), + hash: RESULT_HASH, }; -impl_static_type!(impl Result => RESULT); +impl_static_type!(impl Result, RESULT, RESULT_HASH); + +pub(crate) const OPTION_HASH: Hash = ::rune_macros::hash!(::std::option::Option); pub(crate) static OPTION: &StaticType = &StaticType { name: RawStr::from_str("Option"), - hash: ::rune_macros::hash!(::std::option::Option), + hash: OPTION_HASH, }; -impl_static_type!(impl Option => OPTION); +impl_static_type!(impl Option, OPTION, OPTION_HASH); +pub(crate) const FUNCTION_HASH: Hash = ::rune_macros::hash!(::std::ops::Function); pub(crate) static FUNCTION: &StaticType = &StaticType { name: RawStr::from_str("Function"), - hash: ::rune_macros::hash!(::std::ops::Function), + hash: FUNCTION_HASH, }; +pub(crate) const FORMAT_HASH: Hash = ::rune_macros::hash!(::std::fmt::Format); pub(crate) static FORMAT: &StaticType = &StaticType { name: RawStr::from_str("Format"), - hash: ::rune_macros::hash!(::std::fmt::Format), + hash: FORMAT_HASH, }; +pub(crate) const ORDERING_HASH: Hash = ::rune_macros::hash!(::std::cmp::Ordering); pub(crate) static ORDERING: &StaticType = &StaticType { name: RawStr::from_str("Ordering"), - hash: ::rune_macros::hash!(::std::cmp::Ordering), + hash: ORDERING_HASH, }; -impl_static_type!(Ordering => ORDERING); +impl_static_type!(Ordering, ORDERING, ORDERING_HASH); +pub(crate) const HASH: Hash = ::rune_macros::hash!(::std::any::Type); pub(crate) static TYPE: &StaticType = &StaticType { name: RawStr::from_str("Type"), - hash: ::rune_macros::hash!(::std::any::Type), + hash: HASH, }; -impl_static_type!(rt::Type => TYPE); +impl_static_type!(rt::Type, TYPE, HASH); diff --git a/crates/rune/src/runtime/tests.rs b/crates/rune/src/runtime/tests.rs index 6919edbfa..ff07ed1ab 100644 --- a/crates/rune/src/runtime/tests.rs +++ b/crates/rune/src/runtime/tests.rs @@ -13,7 +13,7 @@ use crate::alloc::prelude::*; use crate::support::Result; use crate::Any; -use super::{Access, AnyObj, Bytes, CoreTypeOf, Mut, Ref, Shared, Value, VmResult}; +use super::{Access, AnyObj, Bytes, Mut, Ref, Shared, TypeHash, Value, VmResult}; #[derive(Debug, PartialEq, Eq, Any)] struct Thing(u32); @@ -47,7 +47,7 @@ fn test_clone_take() -> Result<()> { assert_eq!(Thing(0), v2.into_any::()?); assert!(v3.into_any::().is_err()); let any = v.into_any_obj()?; - assert_eq!(any.type_hash(), Thing::type_hash()); + assert_eq!(any.type_hash(), Thing::HASH); Ok(()) } diff --git a/crates/rune/src/runtime/tuple.rs b/crates/rune/src/runtime/tuple.rs index 1a3637664..50fca3f64 100644 --- a/crates/rune/src/runtime/tuple.rs +++ b/crates/rune/src/runtime/tuple.rs @@ -297,7 +297,7 @@ impl FromValue for OwnedTuple { macro_rules! impl_tuple { // Skip conflicting implementation with `()`. (0) => { - impl_static_type!(() => crate::runtime::static_type::TUPLE); + impl_static_type!((), crate::runtime::static_type::TUPLE, crate::runtime::static_type::TUPLE_HASH); impl FromValue for () { fn from_value(value: Value) -> VmResult { @@ -313,7 +313,7 @@ macro_rules! impl_tuple { }; ($count:expr $(, $ty:ident $var:ident $ignore_count:expr)*) => { - impl_static_type!(impl <$($ty),*> ($($ty,)*) => crate::runtime::static_type::TUPLE); + impl_static_type!(impl <$($ty),*> ($($ty,)*), crate::runtime::static_type::TUPLE, crate::runtime::static_type::TUPLE_HASH); impl <$($ty,)*> FromValue for ($($ty,)*) where diff --git a/crates/rune/src/runtime/type_info.rs b/crates/rune/src/runtime/type_info.rs index 6d0a48c1e..e533215a8 100644 --- a/crates/rune/src/runtime/type_info.rs +++ b/crates/rune/src/runtime/type_info.rs @@ -8,54 +8,99 @@ use crate::Any; use ::rust_alloc::sync::Arc; -/// Type information about a value, that can be printed for human consumption -/// through its [Display][fmt::Display] implementation. #[derive(Debug, TryClone, PartialEq, Eq)] -#[non_exhaustive] -pub enum TypeInfo { +enum TypeInfoKind { /// The static type of a value. StaticType(&'static StaticType), + /// Reference to an external type. + Any(AnyTypeInfo), /// A named type. Typed(Arc), /// A variant. Variant(Arc), - /// Reference to an external type. - Any(AnyTypeInfo), +} + +/// Diagnostical type information for a given type. +/// +/// Has reasonable [`Debug`] and [`Display`] implementations to identify a given +/// type. +/// +/// [`Debug`]: core::fmt::Debug +/// [`Display`]: core::fmt::Display +#[derive(TryClone, PartialEq, Eq)] +#[non_exhaustive] +pub struct TypeInfo { + kind: TypeInfoKind, } impl TypeInfo { + #[inline] + const fn new(kind: TypeInfoKind) -> Self { + Self { kind } + } + /// Construct type info from an statically known [`Any`] type. - pub(crate) fn any() -> Self + #[inline] + pub const fn any() -> Self where T: Any, { - TypeInfo::Any(AnyTypeInfo::__private_new(T::BASE_NAME, T::type_hash())) + Self::any_type_info(T::INFO) + } + + /// Construct type info from an statically known [`Any`] type. + #[doc(hidden)] + #[inline] + pub(crate) const fn any_type_info(type_info: AnyTypeInfo) -> Self { + Self::new(TypeInfoKind::Any(type_info)) + } + + #[doc(hidden)] + pub(crate) const fn static_type(ty: &'static StaticType) -> Self { + Self::new(TypeInfoKind::StaticType(ty)) + } + + #[inline] + pub(crate) const fn typed(rtti: Arc) -> Self { + Self::new(TypeInfoKind::Typed(rtti)) + } + + #[inline] + pub(crate) const fn variant(rtti: Arc) -> Self { + Self::new(TypeInfoKind::Variant(rtti)) } #[cfg(feature = "emit")] pub(crate) fn type_hash(&self) -> Hash { - match self { - TypeInfo::StaticType(ty) => ty.hash, - TypeInfo::Typed(ty) => ty.hash, - TypeInfo::Variant(ty) => ty.hash, - TypeInfo::Any(ty) => ty.hash, + match &self.kind { + TypeInfoKind::StaticType(ty) => ty.hash, + TypeInfoKind::Typed(ty) => ty.hash, + TypeInfoKind::Variant(ty) => ty.hash, + TypeInfoKind::Any(ty) => ty.hash, } } } +impl fmt::Debug for TypeInfo { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.kind.fmt(f) + } +} + impl fmt::Display for TypeInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::StaticType(ty) => { + match &self.kind { + TypeInfoKind::StaticType(ty) => { write!(f, "{}", ty.name)?; } - Self::Typed(rtti) => { + TypeInfoKind::Typed(rtti) => { write!(f, "{}", rtti.item)?; } - Self::Variant(rtti) => { + TypeInfoKind::Variant(rtti) => { write!(f, "{}", rtti.item)?; } - Self::Any(info) => { + TypeInfoKind::Any(info) => { write!(f, "{}", info.name)?; } } @@ -67,18 +112,16 @@ impl fmt::Display for TypeInfo { /// Type information for the [`Any`][crate::Any] type. #[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq)] #[try_clone(copy)] -#[non_exhaustive] pub struct AnyTypeInfo { /// The name of the type. - pub name: RawStr, + pub(crate) name: RawStr, /// The type hash of the item. - pub hash: Hash, + pub(crate) hash: Hash, } impl AnyTypeInfo { /// Private constructor, use at your own risk. - #[doc(hidden)] - pub fn __private_new(name: RawStr, hash: Hash) -> Self { + pub(crate) const fn new(name: RawStr, hash: Hash) -> Self { Self { name, hash } } } diff --git a/crates/rune/src/runtime/type_of.rs b/crates/rune/src/runtime/type_of.rs index 08d7cbbd9..e1056ffe2 100644 --- a/crates/rune/src/runtime/type_of.rs +++ b/crates/rune/src/runtime/type_of.rs @@ -3,43 +3,78 @@ use crate::compile::meta; use crate::runtime::{Mut, Ref, Shared, TypeInfo}; use crate::Hash; -/// Core type of trait. -pub trait CoreTypeOf { - /// Get full type hash, including type parameters. - fn type_hash() -> Hash; +/// Static type hash for a given type. +/// +/// This trait allows you to determine the unique hash of any given type that +/// can be used in Rune through the [`HASH`] associated constant. +/// +/// This trait is usually implemented automatically through the [`Any` derive]. +/// +/// A type hash is unique for types which in Rune are considered the same. This +/// might not be true for types in Rust. For example, `&str` and `String` have +/// the same type hash: +/// +/// ``` +/// use rune::TypeHash; +/// +/// assert_eq!(<&str>::HASH, String::HASH); +/// ``` +/// +/// [`HASH`]: TypeHash::HASH +/// [`Any` derive]: derive@crate::Any +pub trait TypeHash { + /// The complete type hash of the type including type parameters which + /// uniquely identifiers a given type. + /// + /// # Examples + /// + /// ``` + /// use rune::TypeHash; + /// + /// assert_ne!(String::HASH, i64::HASH); + /// + /// fn is_a_string() -> bool where T: TypeHash { + /// matches!(T::HASH, String::HASH) + /// } + /// + /// assert!(is_a_string::()); + /// assert!(!is_a_string::()); + /// ``` + const HASH: Hash; } /// Blanket implementation for references. -impl CoreTypeOf for &T +impl TypeHash for &T where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } /// Blanket implementation for mutable references. -impl CoreTypeOf for &mut T +impl TypeHash for &mut T where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } /// Trait used for Rust types for which we can determine the runtime type of. -pub trait TypeOf: CoreTypeOf { - /// Hash of type parameters. - #[inline] - fn type_parameters() -> Hash { - Hash::EMPTY - } - - /// Access diagnostical information on the value type. +pub trait TypeOf: TypeHash { + /// Type parameters for the type. + /// + /// See [`ParametersBuilder`] for more information. + /// + /// [`ParametersBuilder`]: crate::hash::ParametersBuilder + const PARAMETERS: Hash = Hash::EMPTY; + + /// Diagnostical type information for the current type. + /// + /// Has reasonable [`Debug`] and [`Display`] implementations to identify a + /// given type. + /// + /// [`Debug`]: core::fmt::Debug + /// [`Display`]: core::fmt::Display fn type_info() -> TypeInfo; } @@ -104,10 +139,7 @@ impl TypeOf for &T where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { @@ -120,10 +152,7 @@ impl TypeOf for &mut T where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { @@ -132,14 +161,11 @@ where } /// Blanket implementation for owned references. -impl CoreTypeOf for Ref +impl TypeHash for Ref where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } /// Blanket implementation for owned references. @@ -147,10 +173,7 @@ impl TypeOf for Ref where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { @@ -159,14 +182,11 @@ where } /// Blanket implementation for owned mutable references. -impl CoreTypeOf for Mut +impl TypeHash for Mut where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } /// Blanket implementation for owned mutable references. @@ -174,10 +194,7 @@ impl TypeOf for Mut where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { @@ -186,14 +203,11 @@ where } /// Blanket implementation for owned shared values. -impl CoreTypeOf for Shared +impl TypeHash for Shared where - T: ?Sized + CoreTypeOf, + T: ?Sized + TypeHash, { - #[inline] - fn type_hash() -> Hash { - T::type_hash() - } + const HASH: Hash = T::HASH; } /// Blanket implementation for owned shared values. @@ -201,10 +215,7 @@ impl TypeOf for Shared where T: ?Sized + TypeOf, { - #[inline] - fn type_parameters() -> Hash { - T::type_parameters() - } + const PARAMETERS: Hash = T::PARAMETERS; #[inline] fn type_info() -> TypeInfo { diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index 63e6a147d..c8e349bb7 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -2270,9 +2270,9 @@ impl TypeValue { #[doc(hidden)] pub fn type_info(&self) -> TypeInfo { match self { - TypeValue::Unit => TypeInfo::StaticType(static_type::TUPLE), - TypeValue::Tuple(..) => TypeInfo::StaticType(static_type::TUPLE), - TypeValue::Object(..) => TypeInfo::StaticType(static_type::OBJECT), + TypeValue::Unit => TypeInfo::static_type(static_type::TUPLE), + TypeValue::Tuple(..) => TypeInfo::static_type(static_type::TUPLE), + TypeValue::Object(..) => TypeInfo::static_type(static_type::OBJECT), TypeValue::EmptyStruct(empty) => empty.type_info(), TypeValue::TupleStruct(tuple) => tuple.type_info(), TypeValue::Struct(object) => object.type_info(), @@ -2412,14 +2412,14 @@ impl fmt::Debug for Inline { impl Inline { pub(crate) fn type_info(&self) -> TypeInfo { match self { - Inline::Unit => TypeInfo::StaticType(static_type::TUPLE), - Inline::Bool(..) => TypeInfo::StaticType(static_type::BOOL), - Inline::Byte(..) => TypeInfo::StaticType(static_type::BYTE), - Inline::Char(..) => TypeInfo::StaticType(static_type::CHAR), - Inline::Integer(..) => TypeInfo::StaticType(static_type::INTEGER), - Inline::Float(..) => TypeInfo::StaticType(static_type::FLOAT), - Inline::Type(..) => TypeInfo::StaticType(static_type::TYPE), - Inline::Ordering(..) => TypeInfo::StaticType(static_type::ORDERING), + Inline::Unit => TypeInfo::static_type(static_type::TUPLE), + Inline::Bool(..) => TypeInfo::static_type(static_type::BOOL), + Inline::Byte(..) => TypeInfo::static_type(static_type::BYTE), + Inline::Char(..) => TypeInfo::static_type(static_type::CHAR), + Inline::Integer(..) => TypeInfo::static_type(static_type::INTEGER), + Inline::Float(..) => TypeInfo::static_type(static_type::FLOAT), + Inline::Type(..) => TypeInfo::static_type(static_type::TYPE), + Inline::Ordering(..) => TypeInfo::static_type(static_type::ORDERING), } } @@ -2495,26 +2495,26 @@ pub(crate) enum Mutable { impl Mutable { pub(crate) fn type_info(&self) -> TypeInfo { match self { - Mutable::String(..) => TypeInfo::StaticType(static_type::STRING), - Mutable::Bytes(..) => TypeInfo::StaticType(static_type::BYTES), - Mutable::Vec(..) => TypeInfo::StaticType(static_type::VEC), - Mutable::Tuple(..) => TypeInfo::StaticType(static_type::TUPLE), - Mutable::Object(..) => TypeInfo::StaticType(static_type::OBJECT), - Mutable::RangeFrom(..) => TypeInfo::StaticType(static_type::RANGE_FROM), - Mutable::RangeFull(..) => TypeInfo::StaticType(static_type::RANGE_FULL), - Mutable::RangeInclusive(..) => TypeInfo::StaticType(static_type::RANGE_INCLUSIVE), - Mutable::RangeToInclusive(..) => TypeInfo::StaticType(static_type::RANGE_TO_INCLUSIVE), - Mutable::RangeTo(..) => TypeInfo::StaticType(static_type::RANGE_TO), - Mutable::Range(..) => TypeInfo::StaticType(static_type::RANGE), - Mutable::ControlFlow(..) => TypeInfo::StaticType(static_type::CONTROL_FLOW), - Mutable::Future(..) => TypeInfo::StaticType(static_type::FUTURE), - Mutable::Stream(..) => TypeInfo::StaticType(static_type::STREAM), - Mutable::Generator(..) => TypeInfo::StaticType(static_type::GENERATOR), - Mutable::GeneratorState(..) => TypeInfo::StaticType(static_type::GENERATOR_STATE), - Mutable::Option(..) => TypeInfo::StaticType(static_type::OPTION), - Mutable::Result(..) => TypeInfo::StaticType(static_type::RESULT), - Mutable::Function(..) => TypeInfo::StaticType(static_type::FUNCTION), - Mutable::Format(..) => TypeInfo::StaticType(static_type::FORMAT), + Mutable::String(..) => TypeInfo::static_type(static_type::STRING), + Mutable::Bytes(..) => TypeInfo::static_type(static_type::BYTES), + 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), + Mutable::Generator(..) => TypeInfo::static_type(static_type::GENERATOR), + Mutable::GeneratorState(..) => TypeInfo::static_type(static_type::GENERATOR_STATE), + Mutable::Option(..) => TypeInfo::static_type(static_type::OPTION), + Mutable::Result(..) => TypeInfo::static_type(static_type::RESULT), + Mutable::Function(..) => TypeInfo::static_type(static_type::FUNCTION), + Mutable::Format(..) => TypeInfo::static_type(static_type::FORMAT), Mutable::EmptyStruct(empty) => empty.type_info(), Mutable::TupleStruct(tuple) => tuple.type_info(), Mutable::Struct(object) => object.type_info(), diff --git a/crates/rune/src/runtime/value/data.rs b/crates/rune/src/runtime/value/data.rs index ee16cdde4..e60273fc4 100644 --- a/crates/rune/src/runtime/value/data.rs +++ b/crates/rune/src/runtime/value/data.rs @@ -26,7 +26,7 @@ impl EmptyStruct { /// Get type info for the typed tuple. pub fn type_info(&self) -> TypeInfo { - TypeInfo::Typed(self.rtti.clone()) + TypeInfo::typed(self.rtti.clone()) } } @@ -63,7 +63,7 @@ impl TupleStruct { /// Get type info for the typed tuple. pub fn type_info(&self) -> TypeInfo { - TypeInfo::Typed(self.rtti.clone()) + TypeInfo::typed(self.rtti.clone()) } /// Get the value at the given index in the tuple. @@ -110,7 +110,7 @@ impl Struct { /// Get type info for the typed object. pub fn type_info(&self) -> TypeInfo { - TypeInfo::Typed(self.rtti.clone()) + TypeInfo::typed(self.rtti.clone()) } /// Get the type hash of the object. diff --git a/crates/rune/src/runtime/variant.rs b/crates/rune/src/runtime/variant.rs index eef31bbfc..085e00d79 100644 --- a/crates/rune/src/runtime/variant.rs +++ b/crates/rune/src/runtime/variant.rs @@ -58,7 +58,7 @@ impl Variant { /// Get type info for the variant. pub fn type_info(&self) -> TypeInfo { - TypeInfo::Variant(self.rtti.clone()) + TypeInfo::variant(self.rtti.clone()) } pub(crate) fn partial_eq_with( diff --git a/crates/rune/src/tests.rs b/crates/rune/src/tests.rs index 748540b50..ecbd07319 100644 --- a/crates/rune/src/tests.rs +++ b/crates/rune/src/tests.rs @@ -15,9 +15,9 @@ pub(crate) mod prelude { pub(crate) use crate::module::InstallWith; pub(crate) use crate::parse; pub(crate) use crate::runtime::{ - self, AnyTypeInfo, Bytes, CoreTypeOf, Formatter, Function, InstAddress, MaybeTypeOf, Mut, - Mutable, Object, Output, OwnedTuple, OwnedValue, Protocol, RawAnyGuard, RawStr, Ref, Stack, - Tuple, TypeInfo, TypeOf, UnsafeToRef, VecTuple, VmErrorKind, VmResult, + self, Bytes, Formatter, Function, InstAddress, MaybeTypeOf, Mut, Mutable, Object, Output, + OwnedTuple, OwnedValue, Protocol, RawAnyGuard, RawStr, Ref, Stack, Tuple, TypeHash, + TypeInfo, TypeOf, UnsafeToRef, VecTuple, VmErrorKind, VmResult, }; pub(crate) use crate::support::Result; pub(crate) use crate::tests::{eval, run}; diff --git a/crates/rune/src/tests/bug_344.rs b/crates/rune/src/tests/bug_344.rs index bb6439203..ca9b53696 100644 --- a/crates/rune/src/tests/bug_344.rs +++ b/crates/rune/src/tests/bug_344.rs @@ -58,7 +58,7 @@ fn bug_344_inst_fn() -> Result<()> { context.install(module)?; let runtime = context.runtime()?; - let hash = Hash::associated_function(GuardCheck::type_hash(), "function"); + let hash = Hash::associated_function(GuardCheck::HASH, "function"); let function = runtime.function(hash).expect("expect function"); @@ -120,7 +120,7 @@ fn bug_344_async_inst_fn() -> Result<()> { context.install(module)?; let runtime = context.runtime()?; - let hash = Hash::associated_function(GuardCheck::type_hash(), "function"); + let hash = Hash::associated_function(GuardCheck::HASH, "function"); let function = runtime.function(hash).expect("expect function"); @@ -177,26 +177,21 @@ impl Named for GuardCheck { const BASE_NAME: RawStr = RawStr::from_str("GuardCheck"); } -impl CoreTypeOf for GuardCheck { - fn type_hash() -> Hash { - rune_macros::hash!(GuardCheck) - } +impl TypeHash for GuardCheck { + const HASH: Hash = rune_macros::hash!(GuardCheck); } impl TypeOf for GuardCheck { #[inline] fn type_info() -> TypeInfo { - TypeInfo::Any(AnyTypeInfo::__private_new( - Self::BASE_NAME, - Self::type_hash(), - )) + TypeInfo::any::() } } impl MaybeTypeOf for GuardCheck { #[inline] fn maybe_type_of() -> alloc::Result { - Ok(meta::DocType::new(Self::type_hash())) + Ok(meta::DocType::new(Self::HASH)) } } diff --git a/crates/rune/src/tests/bug_700.rs b/crates/rune/src/tests/bug_700.rs index 03548b0de..44d3214ff 100644 --- a/crates/rune/src/tests/bug_700.rs +++ b/crates/rune/src/tests/bug_700.rs @@ -41,8 +41,8 @@ pub fn test_bug_700() -> Result<()> { assert_eq!( error.into_kind(), VmErrorKind::Expected { - expected: TypeInfo::StaticType(static_type::TUPLE), - actual: TypeInfo::StaticType(static_type::INTEGER) + expected: TypeInfo::static_type(static_type::TUPLE), + actual: TypeInfo::static_type(static_type::INTEGER) } ); diff --git a/crates/rune/src/tests/external_generic.rs b/crates/rune/src/tests/external_generic.rs index aa9f6c6c3..96badbb33 100644 --- a/crates/rune/src/tests/external_generic.rs +++ b/crates/rune/src/tests/external_generic.rs @@ -106,7 +106,7 @@ fn test_generic() -> Result<()> { $( let value = vm.call([stringify!($function_ty)], ()).with_context(|| anyhow!("{}: {}: Working call", stringify!($ty), stringify!($function_ty)))?; let value: Type = rune::from_value(value).with_context(|| anyhow!("{}: {}: Output value", stringify!($ty), stringify!($function_ty)))?; - assert_eq!(Generic::<$ty>::type_hash(), value.into_hash()); + assert_eq!(Generic::<$ty>::HASH, value.into_hash()); )* }; }