Skip to content

Commit

Permalink
rune: Move type of implementations to one place
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Nov 2, 2024
1 parent b56f04d commit 4577bfa
Show file tree
Hide file tree
Showing 21 changed files with 207 additions and 353 deletions.
10 changes: 5 additions & 5 deletions crates/rune-macros/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Derive {
) -> Result<TypeBuilder<'a, syn::Ident>, ()> {
let mut installers = Vec::new();

expand_install_with(cx, &self.input, &tokens, &attr, &mut installers)?;
expand_install_with(cx, &self.input, tokens, attr, &mut installers)?;

if matches!(&self.input.data, syn::Data::Enum(..)) {
if let Some(span) = attr.constructor {
Expand Down Expand Up @@ -563,7 +563,7 @@ where
let Tokens {
alloc,
any_t,
any_from_t,
any_marker_t,
context_error,
fmt,
hash,
Expand All @@ -576,7 +576,7 @@ where
non_null,
raw_value_guard,
result,
static_type_info,
any_type_info,
type_hash_t,
type_of,
unsafe_to_mut,
Expand Down Expand Up @@ -680,7 +680,7 @@ where
#(#attrs)*
impl #impl_generics #type_of for #ident #type_generics #where_clause {
const PARAMETERS: #hash = #type_parameters;
const STATIC_TYPE_INFO: #static_type_info = #static_type_info::any_type_info(<Self as #any_t>::ANY_TYPE_INFO);
const STATIC_TYPE_INFO: #any_type_info = <Self as #any_t>::ANY_TYPE_INFO;
}

#[automatically_derived]
Expand Down Expand Up @@ -751,7 +751,7 @@ where
quote! {
#[automatically_derived]
#(#attrs)*
impl #impl_generics #any_from_t for #ident #type_generics #where_clause {
impl #impl_generics #any_marker_t for #ident #type_generics #where_clause {
}
}
});
Expand Down
8 changes: 4 additions & 4 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,9 @@ impl Context {

Tokens {
alloc: path(m, ["alloc"]),
any_marker_t: path(m, ["__private", "AnyMarker"]),
any_t: path(m, ["Any"]),
any_from_t: path(m, ["__private", "AnyFrom"]),
any_type_info: path(m, ["runtime", "AnyTypeInfo"]),
arc: path(m, ["__private", "Arc"]),
compile_error: path(m, ["compile", "Error"]),
const_construct_t: path(m, ["runtime", "ConstConstruct"]),
Expand Down Expand Up @@ -756,7 +757,6 @@ impl Context {
runtime_error: path(m, ["runtime", "RuntimeError"]),
span: path(m, ["ast", "Span"]),
spanned: path(m, ["ast", "Spanned"]),
static_type_info: path(m, ["runtime", "StaticTypeInfo"]),
string: path(m, ["alloc", "String"]),
to_const_value_t: path(m, ["runtime", "ToConstValue"]),
to_tokens: path(m, ["macros", "ToTokens"]),
Expand Down Expand Up @@ -815,8 +815,9 @@ fn path<const N: usize>(base: &syn::Path, path: [&'static str; N]) -> syn::Path

pub(crate) struct Tokens {
pub(crate) alloc: syn::Path,
pub(crate) any_from_t: syn::Path,
pub(crate) any_marker_t: syn::Path,
pub(crate) any_t: syn::Path,
pub(crate) any_type_info: syn::Path,
pub(crate) arc: syn::Path,
pub(crate) compile_error: syn::Path,
pub(crate) const_construct_t: syn::Path,
Expand Down Expand Up @@ -851,7 +852,6 @@ pub(crate) struct Tokens {
pub(crate) runtime_error: syn::Path,
pub(crate) span: syn::Path,
pub(crate) spanned: syn::Path,
pub(crate) static_type_info: syn::Path,
pub(crate) string: syn::Path,
pub(crate) to_const_value_t: syn::Path,
pub(crate) to_tokens: syn::Path,
Expand Down
30 changes: 30 additions & 0 deletions crates/rune-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mod macro_;
mod module;
mod opaque;
mod parse;
mod path_in;
mod quote;
mod spanned;
mod to_tokens;
Expand Down Expand Up @@ -215,6 +216,20 @@ pub fn hash(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
stream.into()
}

#[doc(hidden)]
#[proc_macro]
pub fn hash_in(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let path_in::PathIn { in_crate, item, .. } =
syn::parse_macro_input!(input as path_in::PathIn<self::hash::Arguments>);

let stream = Context::build(|cx| {
let value = item.build_type_hash(cx)?.into_inner();
Ok(::quote::quote!(#in_crate::Hash(#value)))
});

stream.into()
}

/// Calculate an item reference at compile time.
///
/// # Examples
Expand Down Expand Up @@ -246,6 +261,21 @@ pub fn item(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
stream.into()
}

#[proc_macro]
#[doc(hidden)]
pub fn item_in(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let path_in::PathIn { in_crate, item, .. } = syn::parse_macro_input!(input as path_in::PathIn);

let stream = match self::item::build_item(&item) {
Ok(hash) => {
::quote::quote!(unsafe { #in_crate::Item::from_bytes(&#hash) })
}
Err(error) => to_compile_errors([error]),
};

stream.into()
}

/// Helper to generate bindings for an external type.
///
/// This can *only* be used inside of the `rune` crate itself.
Expand Down
23 changes: 23 additions & 0 deletions crates/rune-macros/src/path_in.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use syn::parse::{Parse, ParseStream};
use syn::Token;

pub(super) struct PathIn<T = syn::Path> {
pub(super) in_crate: syn::Path,
#[allow(unused)]
pub(super) comma_token: Token![,],
pub(super) item: T,
}

impl<T> Parse for PathIn<T>
where
T: Parse,
{
#[inline]
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
in_crate: input.parse()?,
comma_token: input.parse()?,
item: input.parse()?,
})
}
}
2 changes: 1 addition & 1 deletion crates/rune/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ pub trait Any: TypeHash + Named + any::Any {
/// [`Any`] derive instead.
///
/// [`Any`]: derive@Any
pub trait AnyFrom: Any {}
pub trait AnyMarker: Any {}
6 changes: 3 additions & 3 deletions crates/rune/src/compile/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use crate::module::{
TypeSpecification,
};
use crate::runtime::{
ConstConstruct, ConstContext, ConstValue, FunctionHandler, InstAddress, Memory, Output,
Protocol, RuntimeContext, StaticTypeInfo, TypeCheck, TypeInfo, VariantRtti, VmResult,
AnyTypeInfo, ConstConstruct, ConstContext, ConstValue, FunctionHandler, InstAddress, Memory,
Output, Protocol, RuntimeContext, TypeCheck, TypeInfo, VariantRtti, VmResult,
};
use crate::{Hash, Item, ItemBuf};

Expand Down Expand Up @@ -969,7 +969,7 @@ impl Context {
fn install_construct(
&mut self,
hash: Hash,
type_info: &StaticTypeInfo,
type_info: &AnyTypeInfo,
construct: &Arc<dyn ConstConstruct>,
) -> Result<(), ContextError> {
let old = self.construct.try_insert(hash, construct.clone())?;
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::alloc;
use crate::compile::meta;
use crate::hash::Hash;
use crate::runtime::{
self, FromValue, InstAddress, MaybeTypeOf, Memory, Output, StaticTypeInfo, ToReturn, TypeHash,
self, AnyTypeInfo, FromValue, InstAddress, MaybeTypeOf, Memory, Output, ToReturn, TypeHash,
TypeOf, UnsafeToMut, UnsafeToRef, Value, VmErrorKind, VmResult,
};

Expand Down Expand Up @@ -161,7 +161,7 @@ where
T: ?Sized + TypeOf,
{
const PARAMETERS: Hash = T::PARAMETERS;
const STATIC_TYPE_INFO: StaticTypeInfo = T::STATIC_TYPE_INFO;
const STATIC_TYPE_INFO: AnyTypeInfo = T::STATIC_TYPE_INFO;
}

/// Zero-sized marker struct for mutable references.
Expand Down Expand Up @@ -189,7 +189,7 @@ where
T: ?Sized + TypeOf,
{
const PARAMETERS: Hash = T::PARAMETERS;
const STATIC_TYPE_INFO: StaticTypeInfo = T::STATIC_TYPE_INFO;
const STATIC_TYPE_INFO: AnyTypeInfo = T::STATIC_TYPE_INFO;
}

// Fake guard for owned values.
Expand Down
71 changes: 25 additions & 46 deletions crates/rune/src/internal_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@ macro_rules! resolve_context {
};
}

macro_rules! impl_any_type {
(impl $(<$($p:ident),*>)? for $ty:ty, $path:path) => {
macro_rules! impl_one_builtin_type_of {
(impl $(<$($p:ident),*>)? $path:path, $ty:ty) => {
impl $(<$($p,)*>)* $crate::TypeHash for $ty {
const HASH: $crate::Hash = ::rune_macros::hash!($path);
const HASH: $crate::Hash = ::rune_macros::hash_in!(crate, $path);
}

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))
}
const STATIC_TYPE_INFO: $crate::runtime::AnyTypeInfo = $crate::runtime::AnyTypeInfo::new(
{
fn full_name(f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
write!(f, "{}", ::rune_macros::item_in!(crate, $path))
}

full_name
},
<Self as $crate::TypeHash>::HASH,
)
full_name
},
<Self as $crate::TypeHash>::HASH,
);
}

Expand All @@ -44,39 +42,6 @@ macro_rules! impl_any_type {
}
}

/// Build an implementation of `TypeOf` basic of a static type.
macro_rules! impl_static_type {
(impl $(<$($p:ident),*>)? for $ty:ty, $name:ident, $hash:ident) => {
impl $(<$($p,)*>)* $crate::TypeHash for $ty {
const HASH: $crate::Hash = $crate::runtime::static_type::$hash;
}

impl $(<$($p,)*>)* $crate::runtime::TypeOf for $ty
where
$(
$($p: $crate::runtime::MaybeTypeOf,)*
)*
{
const STATIC_TYPE_INFO: $crate::runtime::StaticTypeInfo = $crate::runtime::StaticTypeInfo::static_type($crate::runtime::static_type::$name);
}

impl $(<$($p,)*>)* $crate::runtime::MaybeTypeOf for $ty
where
$(
$($p: $crate::runtime::MaybeTypeOf,)*
)*
{
#[inline]
fn maybe_type_of() -> $crate::alloc::Result<$crate::compile::meta::DocType> {
$crate::compile::meta::DocType::with_generics(
<$ty as $crate::TypeHash>::HASH,
[$($(<$p as $crate::runtime::MaybeTypeOf>::maybe_type_of()?),*)*]
)
}
}
};
}

/// Call the given macro with repeated type arguments and counts.
macro_rules! repeat_macro {
($macro:ident) => {
Expand Down Expand Up @@ -163,3 +128,17 @@ macro_rules! from_value_ref {
}
};
}

macro_rules! impl_builtin_type_of {
(
$(
$(#[$($impl_meta:meta)*])*
impl $(<$($p:ident),*>)? $path:path, $ty:ty;
)*
) => {
$(
$(#[$($impl_meta)*])*
impl_one_builtin_type_of!(impl $(<$($p),*>)* $path, $ty);
)*
}
}
61 changes: 60 additions & 1 deletion crates/rune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ pub(crate) mod doc;
/// Privately exported details.
#[doc(hidden)]
pub mod __private {
pub use crate::any::AnyFrom;
pub use crate::any::AnyMarker;
pub use crate::function_meta::{
FunctionMetaData, FunctionMetaKind, FunctionMetaStatics, MacroMetaData, MacroMetaKind,
};
Expand Down Expand Up @@ -705,5 +705,64 @@ rune_macros::binding! {
impl ::std::string::Utf8Error for core::str::Utf8Error;
}

impl_builtin_type_of! {
impl<T, E> ::std::result::Result, core::result::Result<T, E>;
impl<T> ::std::option::Option, core::option::Option<T>;

impl ::std::bool, bool;
impl ::std::char, char;

impl ::std::i64, i8;
impl ::std::i64, i16;
impl ::std::i64, i32;
impl ::std::i64, i64;
impl ::std::i64, i128;
impl ::std::i64, isize;
impl ::std::u64, u8;
impl ::std::u64, u16;
impl ::std::u64, u32;
impl ::std::u64, u64;
impl ::std::u64, u128;
impl ::std::u64, usize;

impl ::std::f64, f32;
impl ::std::f64, f64;

impl<C, B> ::std::ops::ControlFlow, core::ops::ControlFlow<C, B>;

impl ::std::bytes::Bytes, [u8];

impl ::std::cmp::Ordering, core::cmp::Ordering;

#[cfg(feature = "alloc")]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "alloc")))]
impl ::std::string::String, ::rust_alloc::string::String;
impl ::std::string::String, crate::alloc::Box<str>;
impl ::std::string::String, str;

impl ::std::vec::Vec, [Value];
#[cfg(feature = "alloc")]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "alloc")))]
impl<T> ::std::vec::Vec, ::rust_alloc::vec::Vec<T>;
impl<T> ::std::vec::Vec, crate::alloc::Vec<T>;
impl<T> ::std::vec::Vec, crate::runtime::VecTuple<T>;

impl ::std::tuple::Tuple, crate::runtime::Tuple;

impl ::std::object::Object, crate::runtime::Struct;
impl<T> ::std::object::Object, crate::alloc::HashMap<::rust_alloc::string::String, T>;
impl<T> ::std::object::Object, crate::alloc::HashMap<alloc::String, T>;

#[cfg(feature = "std")]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
impl<T> ::std::object::Object, std::collections::HashMap<::rust_alloc::string::String, T>;

#[cfg(feature = "std")]
#[cfg_attr(rune_docsrs, doc(cfg(feature = "std")))]
impl<T> ::std::object::Object, std::collections::HashMap<alloc::String, T>;

impl ::std::any::Type, crate::runtime::Type;
}

from_value_ref!(Result<Value, Value>, into_result_ref, into_result_mut);
from_value_ref!(Option<Value>, into_option_ref, into_option_mut);
Loading

0 comments on commit 4577bfa

Please sign in to comment.