diff --git a/crates/rune/src/compile/named.rs b/crates/rune/src/compile/named.rs index 47c670530..520ec4907 100644 --- a/crates/rune/src/compile/named.rs +++ b/crates/rune/src/compile/named.rs @@ -3,7 +3,7 @@ use core::fmt; use core::marker::PhantomData; use crate as rune; -use crate::alloc::{Box, String}; +use crate::alloc::String; use crate::module::InstallWith; use crate::{item, Item}; @@ -51,14 +51,6 @@ impl Named for String { const ITEM: &'static Item = item!(::std::string::String); } -impl Named for &str { - const ITEM: &'static Item = item!(::std::string::String); -} - -impl Named for Box { - const ITEM: &'static Item = item!(::std::string::String); -} - impl InstallWith for String {} impl Named for i64 { diff --git a/crates/rune/src/modules/string.rs b/crates/rune/src/modules/string.rs index a65d8eda6..0d0209293 100644 --- a/crates/rune/src/modules/string.rs +++ b/crates/rune/src/modules/string.rs @@ -108,7 +108,7 @@ pub fn module() -> Result { } split!(Function); - split!(Box); + split!(String); split!(char); Ok(m) } @@ -910,7 +910,7 @@ fn split(this: Ref, value: Value) -> VmResult { vm_try!(rune::to_value(Split::new( this, - vm_try!(Box::try_from(s.as_str())) + vm_try!(String::try_from(s.as_str())) ))) } _ => { @@ -1476,9 +1476,9 @@ trait Pattern: 'static + TryClone + Named + FromValue + ToValue + MaybeTypeOf + fn is_empty(&self) -> bool; } -impl Pattern for Box { +impl Pattern for String { fn test(&self, tail: &str) -> VmResult<(bool, usize)> { - if tail.starts_with(self.as_ref()) { + if tail.starts_with(self.as_str()) { VmResult::Ok((true, self.len())) } else { let Some(c) = tail.chars().next() else { @@ -1491,7 +1491,7 @@ impl Pattern for Box { #[inline] fn is_empty(&self) -> bool { - self.as_ref().is_empty() + String::is_empty(self) } } diff --git a/crates/rune/src/runtime/bytes.rs b/crates/rune/src/runtime/bytes.rs index a8b7c21ce..fb1e67a11 100644 --- a/crates/rune/src/runtime/bytes.rs +++ b/crates/rune/src/runtime/bytes.rs @@ -17,7 +17,6 @@ use super::{IntoOutput, RawAnyGuard, Ref, UnsafeToRef, Value, VmResult}; /// A vector of bytes. #[derive(Any, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[rune(static_type = BYTES)] #[rune(item = ::std::bytes)] pub struct Bytes { bytes: Vec, diff --git a/crates/rune/src/runtime/const_value.rs b/crates/rune/src/runtime/const_value.rs index 54336f1ff..a17f905e2 100644 --- a/crates/rune/src/runtime/const_value.rs +++ b/crates/rune/src/runtime/const_value.rs @@ -135,9 +135,9 @@ impl ConstValueKind { match self { ConstValueKind::Inline(value) => value.type_info(), - ConstValueKind::String(..) => TypeInfo::static_type(runtime::static_type::STRING), - ConstValueKind::Bytes(..) => TypeInfo::static_type(runtime::static_type::BYTES), - ConstValueKind::Vec(..) => TypeInfo::static_type(runtime::static_type::VEC), + ConstValueKind::String(..) => TypeInfo::any::(), + ConstValueKind::Bytes(..) => TypeInfo::any::(), + ConstValueKind::Vec(..) => TypeInfo::any::(), ConstValueKind::Tuple(..) => TypeInfo::static_type(runtime::static_type::TUPLE), ConstValueKind::Object(..) => TypeInfo::static_type(runtime::static_type::OBJECT), ConstValueKind::Option(..) => TypeInfo::static_type(runtime::static_type::OPTION), diff --git a/crates/rune/src/runtime/control_flow.rs b/crates/rune/src/runtime/control_flow.rs index a495d2cca..23b2fbfb5 100644 --- a/crates/rune/src/runtime/control_flow.rs +++ b/crates/rune/src/runtime/control_flow.rs @@ -26,7 +26,6 @@ use super::{ /// ``` #[derive(Debug, Clone, TryClone, Any)] #[try_clone(crate)] -#[rune(static_type = CONTROL_FLOW)] #[rune(item = ::std::ops)] pub enum ControlFlow { /// Move on to the next phase of the operation as normal. diff --git a/crates/rune/src/runtime/format.rs b/crates/rune/src/runtime/format.rs index 058603f57..0cb24ad06 100644 --- a/crates/rune/src/runtime/format.rs +++ b/crates/rune/src/runtime/format.rs @@ -41,7 +41,6 @@ impl fmt::Display for AlignmentFromStrError { /// A format specification, wrapping an inner value. #[derive(Any, Debug, Clone, TryClone)] -#[rune(static_type = FORMAT)] #[rune(item = ::std::fmt)] pub struct Format { /// The value being formatted. diff --git a/crates/rune/src/runtime/generator_state.rs b/crates/rune/src/runtime/generator_state.rs index e0a6cb2ab..cb6c90320 100644 --- a/crates/rune/src/runtime/generator_state.rs +++ b/crates/rune/src/runtime/generator_state.rs @@ -50,7 +50,6 @@ use crate::Any; /// # Ok::<_, rune::support::Error>(()) /// ``` #[derive(Any, Debug, TryClone)] -#[rune(static_type = GENERATOR_STATE)] #[rune(item = ::std::ops::generator)] pub enum GeneratorState { /// The generator yielded. diff --git a/crates/rune/src/runtime/range.rs b/crates/rune/src/runtime/range.rs index 144cc7340..e2f6f59e5 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(constructor, static_type = RANGE)] -#[rune(item = ::std::ops)] +#[rune(crate, constructor, item = ::std::ops)] pub struct Range { /// The start value of the range. #[rune(get, set)] diff --git a/crates/rune/src/runtime/range_from.rs b/crates/rune/src/runtime/range_from.rs index b57377630..a58b7c13a 100644 --- a/crates/rune/src/runtime/range_from.rs +++ b/crates/rune/src/runtime/range_from.rs @@ -54,8 +54,7 @@ use crate::Any; /// ``` #[derive(Any, Clone, TryClone)] #[try_clone(crate)] -#[rune(constructor, static_type = RANGE_FROM)] -#[rune(item = ::std::ops)] +#[rune(crate, constructor, item = ::std::ops)] pub struct RangeFrom { /// The start value of the range. #[rune(get, set)] diff --git a/crates/rune/src/runtime/range_full.rs b/crates/rune/src/runtime/range_full.rs index 93115e7dd..e921299c9 100644 --- a/crates/rune/src/runtime/range_full.rs +++ b/crates/rune/src/runtime/range_full.rs @@ -32,8 +32,7 @@ use crate::Any; /// ``` #[derive(Any, Default, Clone, TryClone)] #[try_clone(crate)] -#[rune(constructor, static_type = RANGE_FULL)] -#[rune(item = ::std::ops)] +#[rune(crate, constructor, item = ::std::ops)] pub struct RangeFull; impl RangeFull { diff --git a/crates/rune/src/runtime/range_inclusive.rs b/crates/rune/src/runtime/range_inclusive.rs index 70095d6ed..26695a109 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(constructor, static_type = RANGE_INCLUSIVE)] -#[rune(item = ::std::ops)] +#[rune(crate, constructor, item = ::std::ops)] pub struct RangeInclusive { /// The start value of the range. #[rune(get, set)] diff --git a/crates/rune/src/runtime/range_to.rs b/crates/rune/src/runtime/range_to.rs index f11d56b68..f4e2d2700 100644 --- a/crates/rune/src/runtime/range_to.rs +++ b/crates/rune/src/runtime/range_to.rs @@ -44,8 +44,7 @@ use crate::Any; #[derive(Any, Clone, TryClone)] #[try_clone(crate)] #[rune(crate)] -#[rune(constructor, static_type = RANGE_TO)] -#[rune(item = ::std::ops)] +#[rune(constructor, item = ::std::ops)] pub struct RangeTo { /// The end value of the range. #[rune(get, set)] diff --git a/crates/rune/src/runtime/range_to_inclusive.rs b/crates/rune/src/runtime/range_to_inclusive.rs index 3ca5f5bd1..c3a05540f 100644 --- a/crates/rune/src/runtime/range_to_inclusive.rs +++ b/crates/rune/src/runtime/range_to_inclusive.rs @@ -42,8 +42,7 @@ use crate::Any; /// # Ok::<_, rune::support::Error>(()) /// ``` #[derive(Any, Clone, TryClone)] -#[rune(constructor, static_type = RANGE_TO_INCLUSIVE)] -#[rune(item = ::std::ops)] +#[rune(constructor, item = ::std::ops)] pub struct RangeToInclusive { /// The end value of the range. #[rune(get, set)] diff --git a/crates/rune/src/runtime/static_type.rs b/crates/rune/src/runtime/static_type.rs index 5625ba794..8bcae6f20 100644 --- a/crates/rune/src/runtime/static_type.rs +++ b/crates/rune/src/runtime/static_type.rs @@ -48,6 +48,63 @@ impl hash::Hash for StaticType { } } +macro_rules! any_type { + ( + $( + $(#[$($meta:meta)*])* + $path:path { + $( + $(#[$($impl_meta:meta)*])* + impl $(<$($p:ident),*>)? for $ty:ty; + )* + } + )* + ) => { + $( + $( + $(#[$($impl_meta)*])* + impl $(<$($p,)*>)* $crate::TypeHash for $ty { + const HASH: $crate::Hash = ::rune_macros::hash!($path); + } + + $(#[$($impl_meta)*])* + impl $(<$($p,)*>)* $crate::runtime::TypeOf for $ty + where + $( + $($p: $crate::runtime::MaybeTypeOf,)* + )* + { + const STATIC_TYPE_INFO: $crate::runtime::StaticTypeInfo = $crate::runtime::StaticTypeInfo::any_type_info( + $crate::runtime::AnyTypeInfo::new( + { + fn full_name(f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { + write!(f, "{}", ::rune_macros::item!($path)) + } + + full_name + }, + ::HASH, + ) + ); + } + + $(#[$($impl_meta)*])* + impl $(<$($p,)*>)* $crate::runtime::MaybeTypeOf for $ty + where + $( + $($p: $crate::runtime::MaybeTypeOf,)* + )* + { + #[inline] + fn maybe_type_of() -> $crate::alloc::Result<$crate::compile::meta::DocType> { + Ok($crate::compile::meta::DocType::new(<$ty as $crate::TypeHash>::HASH)) + } + } + )* + )* + } +} + macro_rules! static_type { ( $( @@ -77,19 +134,19 @@ macro_rules! static_type { } } -static_type! { +any_type! { /// The specialized type information for a bool type. - pub(crate) static [BOOL, BOOL_HASH] = ::std::bool { + ::std::bool { impl for bool; } /// The specialized type information for a char type. - pub(crate) static [CHAR, CHAR_HASH] = ::std::char { + ::std::char { impl for char; } /// The specialized type information for a integer type. - pub(crate) static [SIGNED, SIGNED_HASH] = ::std::i64 { + ::std::i64 { impl for i8; impl for i16; impl for i32; @@ -99,7 +156,7 @@ static_type! { } /// The specialized type information for an unsigned integer type. - pub(crate) static [UNSIGNED, UNSIGNED_HASH] = ::std::u64 { + ::std::u64 { impl for u8; impl for u16; impl for u32; @@ -109,13 +166,26 @@ static_type! { } /// The specialized type information for a float type. - pub(crate) static [FLOAT, FLOAT_HASH] = ::std::f64 { + ::std::f64 { impl for f32; impl for f64; } + ::std::ops::ControlFlow { + impl for ControlFlow; + } + + /// The specialized type information for the [`Bytes`] type. + ::std::bytes::Bytes { + impl for [u8]; + } + + ::std::cmp::Ordering { + impl for Ordering; + } + /// The specialized type information for a float type. - pub(crate) static [STRING, STRING_HASH] = ::std::string::String { + ::std::string::String { #[cfg(feature = "alloc")] #[cfg_attr(rune_docsrs, doc(cfg(feature = "alloc")))] impl for ::rust_alloc::string::String; @@ -124,13 +194,8 @@ static_type! { impl for str; } - /// The specialized type information for the [`Bytes`] type. - pub(crate) static [BYTES, BYTES_HASH] = ::std::bytes::Bytes { - impl for [u8]; - } - /// The specialized type information for the [`Vec`] type. - pub(crate) static [VEC, VEC_HASH] = ::std::vec::Vec { + ::std::vec::Vec { impl for [rt::Value]; #[cfg(feature = "alloc")] #[cfg_attr(rune_docsrs, doc(cfg(feature = "alloc")))] @@ -138,7 +203,9 @@ static_type! { impl for alloc::Vec; impl for rt::VecTuple; } +} +static_type! { /// The specialized type information for the [`Tuple`] type. pub(crate) static [TUPLE, TUPLE_HASH] = ::std::tuple::Tuple { impl for rt::OwnedTuple; @@ -159,28 +226,10 @@ static_type! { impl for ::std::collections::HashMap; } - pub(crate) static [RANGE_FROM, RANGE_FROM_HASH] = ::std::ops::RangeFrom {} - - pub(crate) static [RANGE_FULL, RANGE_FULL_HASH] = ::std::ops::RangeFull {} - - pub(crate) static [RANGE_INCLUSIVE, RANGE_INCLUSIVE_HASH] = ::std::ops::RangeInclusive {} - - pub(crate) static [RANGE_TO_INCLUSIVE, RANGE_TO_INCLUSIVE_HASH] = ::std::ops::RangeToInclusive {} - - pub(crate) static [RANGE_TO, RANGE_TO_HASH] = ::std::ops::RangeTo {} - - pub(crate) static [RANGE, RANGE_HASH] = ::std::ops::Range {} - - pub(crate) static [CONTROL_FLOW, CONTROL_FLOW_HASH] = ::std::ops::ControlFlow { - impl for ControlFlow; - } - pub(crate) static [FUTURE, FUTURE_HASH] = ::std::future::Future {} pub(crate) static [GENERATOR, GENERATOR_HASH] = ::std::ops::generator::Generator {} - pub(crate) static [GENERATOR_STATE, GENERATOR_STATE_HASH] = ::std::ops::generator::GeneratorState {} - pub(crate) static [STREAM, STREAM_HASH] = ::std::stream::Stream {} pub(crate) static [RESULT, RESULT_HASH] = ::std::result::Result { @@ -193,12 +242,6 @@ static_type! { pub(crate) static [FUNCTION, FUNCTION_HASH] = ::std::ops::Function {} - pub(crate) static [FORMAT, FORMAT_HASH] = ::std::fmt::Format {} - - pub(crate) static [ORDERING, ORDERING_HASH] = ::std::cmp::Ordering { - impl for Ordering; - } - pub(crate) static [TYPE, TYPE_HASH] = ::std::any::Type { impl for rt::Type; } diff --git a/crates/rune/src/runtime/type_info.rs b/crates/rune/src/runtime/type_info.rs index 1bf434bbd..1bc5a6f19 100644 --- a/crates/rune/src/runtime/type_info.rs +++ b/crates/rune/src/runtime/type_info.rs @@ -1,9 +1,11 @@ use core::fmt; +use core::hash; use crate as rune; use crate::alloc::prelude::*; +use crate::compile::Named; use crate::hash::Hash; -use crate::Any; +use crate::{Any, TypeHash}; use ::rust_alloc::sync::Arc; @@ -49,6 +51,15 @@ impl TypeInfo { Self::any_type_info(T::ANY_TYPE_INFO) } + /// Construct type info from an statically known [`Named`] type. + #[inline] + pub const fn named() -> Self + where + T: Named + TypeHash, + { + Self::any_type_info(AnyTypeInfo::new(T::full_name, T::HASH)) + } + /// Construct type info from an statically known [`Any`] type. #[doc(hidden)] #[inline] @@ -128,7 +139,7 @@ impl From for TypeInfo { } /// Type information for the [`Any`][crate::Any] type. -#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, TryClone, Clone, Copy)] #[try_clone(copy)] pub struct AnyTypeInfo { /// Formatter to display a full name. @@ -152,3 +163,19 @@ impl fmt::Display for AnyTypeInfo { } pub type FullNameFn = fn(&mut fmt::Formatter<'_>) -> fmt::Result; + +impl PartialEq for AnyTypeInfo { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.hash == other.hash + } +} + +impl Eq for AnyTypeInfo {} + +impl hash::Hash for AnyTypeInfo { + #[inline] + fn hash(&self, state: &mut H) { + self.hash.hash(state); + } +} diff --git a/crates/rune/src/runtime/value/inline.rs b/crates/rune/src/runtime/value/inline.rs index cbcb84020..e79d463aa 100644 --- a/crates/rune/src/runtime/value/inline.rs +++ b/crates/rune/src/runtime/value/inline.rs @@ -9,6 +9,7 @@ use crate::hash::Hash; use crate::runtime::{ static_type, Protocol, RuntimeError, Type, TypeInfo, VmErrorKind, VmIntegerRepr, VmResult, }; +use crate::TypeHash; use super::err; @@ -190,13 +191,13 @@ impl Inline { pub(crate) fn type_info(&self) -> TypeInfo { match self { Inline::Unit => TypeInfo::static_type(static_type::TUPLE), - Inline::Bool(..) => TypeInfo::static_type(static_type::BOOL), - Inline::Char(..) => TypeInfo::static_type(static_type::CHAR), - Inline::Unsigned(..) => TypeInfo::static_type(static_type::UNSIGNED), - Inline::Signed(..) => TypeInfo::static_type(static_type::SIGNED), - Inline::Float(..) => TypeInfo::static_type(static_type::FLOAT), + Inline::Bool(..) => TypeInfo::named::(), + Inline::Char(..) => TypeInfo::named::(), + Inline::Unsigned(..) => TypeInfo::named::(), + Inline::Signed(..) => TypeInfo::named::(), + Inline::Float(..) => TypeInfo::named::(), Inline::Type(..) => TypeInfo::static_type(static_type::TYPE), - Inline::Ordering(..) => TypeInfo::static_type(static_type::ORDERING), + Inline::Ordering(..) => TypeInfo::named::(), } } @@ -207,13 +208,13 @@ impl Inline { pub(crate) fn type_hash(&self) -> Hash { match self { Inline::Unit => static_type::TUPLE.hash, - Inline::Bool(..) => static_type::BOOL.hash, - Inline::Char(..) => static_type::CHAR.hash, - Inline::Signed(..) => static_type::SIGNED.hash, - Inline::Unsigned(..) => static_type::UNSIGNED.hash, - Inline::Float(..) => static_type::FLOAT.hash, + Inline::Bool(..) => bool::HASH, + Inline::Char(..) => char::HASH, + Inline::Signed(..) => i64::HASH, + Inline::Unsigned(..) => u64::HASH, + Inline::Float(..) => f64::HASH, Inline::Type(..) => static_type::TYPE.hash, - Inline::Ordering(..) => static_type::ORDERING.hash, + Inline::Ordering(..) => Ordering::HASH, } } } diff --git a/crates/rune/src/runtime/vec.rs b/crates/rune/src/runtime/vec.rs index c2a705da7..19928058a 100644 --- a/crates/rune/src/runtime/vec.rs +++ b/crates/rune/src/runtime/vec.rs @@ -40,7 +40,6 @@ use super::{ /// ``` #[derive(Default, Any)] #[repr(transparent)] -#[rune(static_type = VEC)] #[rune(item = ::std::vec)] pub struct Vec { inner: alloc::Vec, diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 7550251ed..d4a200689 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -14,15 +14,15 @@ use crate::modules::{option, result}; use crate::runtime; use super::{ - budget, static_type, Args, Awaited, BorrowMut, BorrowRefRepr, Bytes, Call, ControlFlow, - DynArgs, DynGuardedArgs, EmptyStruct, Format, FormatSpec, Formatter, FromValue, Function, - Future, Generator, GeneratorState, GuardedArgs, Inline, Inst, InstAddress, InstAssignOp, - InstOp, InstRange, InstTarget, InstValue, InstVariant, MutRepr, Mutable, Object, Output, - OwnedTuple, Pair, Panic, Protocol, ProtocolCaller, Range, RangeFrom, RangeFull, RangeInclusive, - RangeTo, RangeToInclusive, RefRepr, RuntimeContext, Select, SelectFuture, Stack, Stream, - Struct, Type, TypeCheck, TypeHash, TypeInfo, TypeOf, Unit, UnitFn, UnitStorage, Value, Variant, - VariantData, Vec, VmDiagnostics, VmDiagnosticsObj, VmError, VmErrorKind, VmExecution, VmHalt, - VmIntegerRepr, VmResult, VmSendExecution, + budget, Args, Awaited, BorrowMut, BorrowRefRepr, Bytes, Call, ControlFlow, DynArgs, + DynGuardedArgs, EmptyStruct, Format, FormatSpec, Formatter, FromValue, Function, Future, + Generator, GeneratorState, GuardedArgs, Inline, Inst, InstAddress, InstAssignOp, InstOp, + InstRange, InstTarget, InstValue, InstVariant, MutRepr, Mutable, Object, Output, OwnedTuple, + Pair, Panic, Protocol, ProtocolCaller, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, + RangeToInclusive, RefRepr, RuntimeContext, Select, SelectFuture, Stack, Stream, Struct, Type, + TypeCheck, TypeHash, TypeInfo, TypeOf, Unit, UnitFn, UnitStorage, Value, Variant, VariantData, + Vec, VmDiagnostics, VmDiagnosticsObj, VmError, VmErrorKind, VmExecution, VmHalt, VmIntegerRepr, + VmResult, VmSendExecution, }; /// Helper to take a value, replacing the old one with empty. @@ -1272,9 +1272,9 @@ impl Vm { macro_rules! convert { ($from:ty, $value:expr) => { match ty.into_hash() { - static_type::FLOAT_HASH => Value::from($value as f64), - static_type::UNSIGNED_HASH => Value::from($value as u64), - static_type::SIGNED_HASH => Value::from($value as i64), + f64::HASH => Value::from($value as f64), + u64::HASH => Value::from($value as u64), + i64::HASH => Value::from($value as i64), ty => { return err(VmErrorKind::UnsupportedAs { value: TypeInfo::from(<$from as TypeOf>::STATIC_TYPE_INFO), diff --git a/crates/rune/src/tests/bug_700.rs b/crates/rune/src/tests/bug_700.rs index c7b66ce68..be37008c2 100644 --- a/crates/rune/src/tests/bug_700.rs +++ b/crates/rune/src/tests/bug_700.rs @@ -42,7 +42,7 @@ pub fn test_bug_700() -> Result<()> { error.into_kind(), VmErrorKind::Expected { expected: TypeInfo::static_type(static_type::TUPLE), - actual: TypeInfo::static_type(static_type::SIGNED) + actual: TypeInfo::named::() } );