From 921051a38b3300fac1366c4b05ddffec8f85990d Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Fri, 12 May 2023 23:37:51 +0200 Subject: [PATCH] Clean up naming (#516) * Rework module compat * Cleaner traits and structs * Rename functions to be less obscure --- book/src/field_functions.md | 4 +- book/src/instance_functions.md | 9 +- book/src/template_literals.md | 2 +- crates/rune-core/src/hash.rs | 6 +- crates/rune-macros/src/any.rs | 6 +- crates/rune-macros/src/context.rs | 40 ++- crates/rune-macros/src/function.rs | 21 +- crates/rune-modules/src/fs.rs | 2 +- crates/rune-modules/src/http.rs | 4 +- crates/rune-modules/src/process.rs | 12 +- crates/rune-modules/src/rand.rs | 8 +- crates/rune-wasm/src/http.rs | 4 +- crates/rune-wasm/src/time.rs | 2 +- crates/rune/.gitignore | 1 + crates/rune/Cargo.toml | 1 + crates/rune/src/compile/context.rs | 8 +- crates/rune/src/compile/meta.rs | 8 +- crates/rune/src/compile/unit_builder.rs | 16 +- crates/rune/src/module.rs | 10 +- crates/rune/src/module/function_meta.rs | 275 +++++------------- crates/rune/src/module/function_traits.rs | 106 +++---- crates/rune/src/module/module.rs | 176 ++++++----- crates/rune/src/modules/any.rs | 2 +- crates/rune/src/modules/bytes.rs | 14 +- crates/rune/src/modules/char.rs | 12 +- .../rune/src/modules/collections/hash_map.rs | 32 +- .../rune/src/modules/collections/hash_set.rs | 30 +- .../rune/src/modules/collections/vec_deque.rs | 32 +- crates/rune/src/modules/float.rs | 14 +- crates/rune/src/modules/fmt.rs | 2 +- crates/rune/src/modules/generator.rs | 10 +- crates/rune/src/modules/int.rs | 48 +-- crates/rune/src/modules/io.rs | 2 +- crates/rune/src/modules/iter.rs | 42 +-- crates/rune/src/modules/object.rs | 20 +- crates/rune/src/modules/ops.rs | 22 +- crates/rune/src/modules/option.rs | 22 +- crates/rune/src/modules/result.rs | 14 +- crates/rune/src/modules/stream.rs | 4 +- crates/rune/src/modules/string.rs | 54 ++-- crates/rune/src/modules/vec.rs | 22 +- crates/rune/src/runtime/function.rs | 41 +-- crates/rune/src/runtime/protocol_caller.rs | 2 +- crates/rune/src/runtime/value.rs | 2 +- crates/rune/src/runtime/vm.rs | 10 +- crates/rune/src/tests/bug_326.rs | 2 +- crates/rune/src/tests/bug_344.rs | 10 +- crates/rune/src/tests/external_ops.rs | 8 +- crates/rune/src/tests/type_name_native.rs | 4 +- crates/rune/tests/generic_native.rs | 4 +- crates/rune/tests/ui.rs | 5 + crates/rune/tests/ui/install_with_compat.rs | 10 + .../rune/tests/ui/install_with_compat.stderr | 5 + examples/examples/custom_instance_fn.rs | 2 +- examples/examples/custom_mul.rs | 2 +- examples/examples/references.rs | 2 +- 56 files changed, 582 insertions(+), 646 deletions(-) create mode 100644 crates/rune/.gitignore create mode 100644 crates/rune/tests/ui.rs create mode 100644 crates/rune/tests/ui/install_with_compat.rs create mode 100644 crates/rune/tests/ui/install_with_compat.stderr diff --git a/book/src/field_functions.md b/book/src/field_functions.md index 95d3eea6e..f58390650 100644 --- a/book/src/field_functions.md +++ b/book/src/field_functions.md @@ -48,7 +48,7 @@ are: | [`Protocol::SHR_ASSIGN`] | `#[rune(shr_assign)]` | The `>>=` operation. | | [`Protocol::REM_ASSIGN`] | `#[rune(rem_assign)]` | The `%=` operation. | -The manual way to register these functions is to use the new `Module::field_fn` +The manual way to register these functions is to use the new `Module::field_function` function. This clearly showcases that there's no relationship between the field used and the function registered: @@ -67,7 +67,7 @@ impl External { } let mut module = Module::new(); -module.field_fn(Protocol::GET, "field", External::field_get)?; +module.field_function(Protocol::GET, "field", External::field_get)?; ``` Would allow for this in Rune: diff --git a/book/src/instance_functions.md b/book/src/instance_functions.md index f7ffe074d..33b65f67d 100644 --- a/book/src/instance_functions.md +++ b/book/src/instance_functions.md @@ -46,9 +46,9 @@ be stabilized and documented in a future release. ## Defining instance functions in Rust Native instance functions are added to a runtime environment using the -[`Module::inst_fn`] and [`Module::async_inst_fn`] functions. The type is -identified as the first argument of the instance function, and must be a type -registered in the module using [`Module::ty`]. +[`Module::associated_function`] function. The type is identified as the first +argument of the instance function, and must be a type registered in the module +using [`Module::ty`]. ```rust,noplaypen {{#include ../../examples/examples/custom_instance_fn.rs}} @@ -62,7 +62,6 @@ output: 11 For more examples on how modules can be used you can have a look at the source for the [`rune-modules`] crate. -[`Module::inst_fn`]: https://docs.rs/rune/0/rune/struct.Module.html#method.inst_fn -[`Module::async_inst_fn`]: https://docs.rs/rune/0/rune/struct.Module.html#method.async_inst_fn +[`Module::associated_function`]: https://docs.rs/rune/0/rune/struct.Module.html#method.associated_function [`Module::ty`]: https://docs.rs/rune/0/rune/struct.Module.html#method.ty [`rune-modules`]: https://github.com/rune-rs/rune/tree/main/crates/rune-modules diff --git a/book/src/template_literals.md b/book/src/template_literals.md index 9f34be062..d1de9f243 100644 --- a/book/src/template_literals.md +++ b/book/src/template_literals.md @@ -47,7 +47,7 @@ impl StatusCode { pub fn module() -> Result { let mut module = Module::new(["http"]); - module.inst_fn(Protocol::STRING_DISPLAY, StatusCode::display)?; + module.associated_function(Protocol::STRING_DISPLAY, StatusCode::display)?; Ok(module) } ``` diff --git a/crates/rune-core/src/hash.rs b/crates/rune-core/src/hash.rs index 0e1a5a9f4..6488bf972 100644 --- a/crates/rune-core/src/hash.rs +++ b/crates/rune-core/src/hash.rs @@ -104,7 +104,7 @@ impl Hash { /// Construct a hash to an instance function, where the instance is a /// pre-determined type. #[inline] - pub fn instance_function(type_hash: Hash, name: N) -> Self + pub fn associated_function(type_hash: Hash, name: N) -> Self where N: IntoHash, { @@ -114,7 +114,7 @@ impl Hash { /// Construct a hash corresponding to a field function. #[inline] - pub fn field_fn(protocol: Protocol, type_hash: Hash, name: N) -> Self + pub fn field_function(protocol: Protocol, type_hash: Hash, name: N) -> Self where N: IntoHash, { @@ -123,7 +123,7 @@ impl Hash { /// Construct an index function. #[inline] - pub fn index_fn(protocol: Protocol, type_hash: Hash, index: Hash) -> Self { + pub fn index_function(protocol: Protocol, type_hash: Hash, index: Hash) -> Self { Self(INDEX_FUNCTION_HASH ^ ((type_hash.0 ^ protocol.hash.0) ^ index.0)) } diff --git a/crates/rune-macros/src/any.rs b/crates/rune-macros/src/any.rs index 3c0da04fd..845e2b4ae 100644 --- a/crates/rune-macros/src/any.rs +++ b/crates/rune-macros/src/any.rs @@ -383,7 +383,7 @@ fn expand_enum_install_with( } let is_variant = quote! { - module.inst_fn(#protocol::IS_VARIANT, |this: &Self, index: usize| { + module.associated_function(#protocol::IS_VARIANT, |this: &Self, index: usize| { match (this, index) { #(#is_variant,)* _ => false, @@ -395,7 +395,7 @@ fn expand_enum_install_with( for (field, matches) in field_fns { installers.push(quote! { - module.field_fn(#protocol::GET, #field, |this: &Self| { + module.field_function(#protocol::GET, #field, |this: &Self| { match this { #(#matches,)* _ => return #vm_result::__rune_macros__unsupported_object_field_get(::type_info()), @@ -406,7 +406,7 @@ fn expand_enum_install_with( for (index, matches) in index_fns { installers.push(quote! { - module.index_fn(#protocol::GET, #index, |this: &Self| { + module.index_function(#protocol::GET, #index, |this: &Self| { match this { #(#matches,)* _ => return #vm_result::__rune_macros__unsupported_tuple_index_get(::type_info()), diff --git a/crates/rune-macros/src/context.rs b/crates/rune-macros/src/context.rs index 0e37b7b14..b41dc8733 100644 --- a/crates/rune-macros/src/context.rs +++ b/crates/rune-macros/src/context.rs @@ -177,11 +177,11 @@ impl Context { GenerateTarget::Named { field_ident, field_name } => { if let Some(custom) = &protocol.custom { quote_spanned! { field.span() => - module.field_fn(#protocol_field, #field_name, #custom)?; + module.field_function(#protocol_field, #field_name, #custom)?; } } else { quote_spanned! { field.span() => - module.field_fn(#protocol_field, #field_name, |s: &mut Self, value: #ty| { + module.field_function(#protocol_field, #field_name, |s: &mut Self, value: #ty| { s.#field_ident $op value; })?; } @@ -190,11 +190,11 @@ impl Context { GenerateTarget::Numbered { field_index } => { if let Some(custom) = &protocol.custom { quote_spanned! { field.span() => - module.index_fn(#protocol_field, #field_index, #custom)?; + module.index_function(#protocol_field, #field_index, #custom)?; } } else { quote_spanned! { field.span() => - module.index_fn(#protocol_field, #field_index, |s: &mut Self, value: #ty| { + module.index_function(#protocol_field, #field_index, |s: &mut Self, value: #ty| { s.#field_index $op value; })?; } @@ -271,7 +271,7 @@ impl Context { let protocol = g.tokens.protocol(PROTOCOL_GET); quote_spanned! { g.field.span() => - module.field_fn(#protocol, #field_name, |s: &Self| #access)?; + module.field_function(#protocol, #field_name, |s: &Self| #access)?; } } GenerateTarget::Numbered { field_index } => { @@ -284,7 +284,7 @@ impl Context { let protocol = g.tokens.protocol(PROTOCOL_GET); quote_spanned! { g.field.span() => - module.index_fn(#protocol, #field_index, |s: &Self| #access)?; + module.index_function(#protocol, #field_index, |s: &Self| #access)?; } } } @@ -305,14 +305,14 @@ impl Context { match target { GenerateTarget::Named { field_ident, field_name } => { quote_spanned! { g.field.span() => - module.field_fn(#protocol, #field_name, |s: &mut Self, value: #ty| { + module.field_function(#protocol, #field_name, |s: &mut Self, value: #ty| { s.#field_ident = value; })?; } } GenerateTarget::Numbered { field_index } => { quote_spanned! { g.field.span() => - module.index_fn(#protocol, #field_index, |s: &mut Self, value: #ty| { + module.index_function(#protocol, #field_index, |s: &mut Self, value: #ty| { s.#field_index = value; })?; } @@ -436,11 +436,11 @@ impl Context { } else if meta.path == MODULE { // Parse `#[rune(module = )]` meta.input.parse::()?; - attr.module = Some(syn::Path::parse_mod_style(meta.input)?); + attr.module = Some(parse_path_compat(meta.input)?); } else if meta.path == INSTALL_WITH { // Parse `#[rune(install_with = )]` meta.input.parse::()?; - attr.install_with = Some(syn::Path::parse_mod_style(meta.input)?); + attr.install_with = Some(parse_path_compat(meta.input)?); } else { return Err(syn::Error::new_spanned( &meta.path, @@ -518,7 +518,7 @@ impl Context { }; input.parse::()?; - Ok(Some(syn::Path::parse_mod_style(input)?)) + Ok(Some(parse_path_compat(input)?)) } /// Build an inner spanned decoder from an iterator. @@ -706,6 +706,24 @@ impl Context { } } +fn parse_path_compat(input: ParseStream<'_>) -> syn::Result { + if input.peek(syn::LitStr) { + let path = input + .parse::()? + .parse_with(syn::Path::parse_mod_style)?; + + return Err(syn::Error::new_spanned( + &path, + format_args!( + "String literals are no longer supported here, use a path like `{}`", + path.to_token_stream() + ), + )); + } + + syn::Path::parse_mod_style(input) +} + fn path(base: &syn::Path, path: [&'static str; N]) -> syn::Path { let mut base = base.clone(); diff --git a/crates/rune-macros/src/function.rs b/crates/rune-macros/src/function.rs index e3a07965f..48df35879 100644 --- a/crates/rune-macros/src/function.rs +++ b/crates/rune-macros/src/function.rs @@ -277,15 +277,6 @@ impl Function { (false, name, arguments) }; - let function = match (instance, self_type.is_some(), self.sig.asyncness.is_some()) { - (true, _, false) => "instance", - (true, _, true) => "async_instance", - (_, true, false) => "function_with", - (_, true, true) => "async_function_with", - (_, _, false) => "function", - (_, _, true) => "async_function", - }; - if !instance && self_type.is_none() { name = { let mut out = syn::ExprArray { @@ -330,6 +321,8 @@ impl Function { } } + let function = if instance { "instance" } else { "function" }; + let meta_kind = syn::Ident::new(function, self.sig.span()); let mut stream = TokenStream::new(); @@ -348,10 +341,12 @@ impl Function { let arguments = &self.arguments; let docs = &self.docs; - let meta_kind = if let Some(self_type) = self_type { - quote!(#meta_kind::<#self_type, _, _, _>) + let build_with = if instance { + None + } else if let Some(self_type) = self_type { + Some(quote!(.build_associated::<#self_type>())) } else { - meta_kind.into_token_stream() + Some(quote!(.build())) }; let meta_vis = &self.vis; @@ -364,7 +359,7 @@ impl Function { #attr #meta_vis fn #meta_fn() -> rune::__private::FunctionMetaData { rune::__private::FunctionMetaData { - kind: rune::__private::FunctionMetaKind::#meta_kind(#name, #real_fn_path), + kind: rune::__private::FunctionMetaKind::#meta_kind(#name, #real_fn_path)#build_with, name: #name_string, docs: &#docs[..], arguments: &#arguments[..], diff --git a/crates/rune-modules/src/fs.rs b/crates/rune-modules/src/fs.rs index 0b69afca2..b757bf566 100644 --- a/crates/rune-modules/src/fs.rs +++ b/crates/rune-modules/src/fs.rs @@ -34,7 +34,7 @@ use rune::{Module, ContextError}; /// Construct the `fs` module. pub fn module(_stdio: bool) -> Result { let mut module = Module::with_crate("fs"); - module.async_function(["read_to_string"], read_to_string)?; + module.function(["read_to_string"], read_to_string)?; Ok(module) } diff --git a/crates/rune-modules/src/http.rs b/crates/rune-modules/src/http.rs index 4ddd5f299..875ef1436 100644 --- a/crates/rune-modules/src/http.rs +++ b/crates/rune-modules/src/http.rs @@ -77,8 +77,8 @@ pub fn module(_stdio: bool) -> Result { module.function_meta(RequestBuilder::header)?; module.function_meta(RequestBuilder::body_bytes)?; - module.inst_fn(Protocol::STRING_DISPLAY, Error::display)?; - module.inst_fn(Protocol::STRING_DISPLAY, StatusCode::display)?; + module.associated_function(Protocol::STRING_DISPLAY, Error::display)?; + module.associated_function(Protocol::STRING_DISPLAY, StatusCode::display)?; Ok(module) } diff --git a/crates/rune-modules/src/process.rs b/crates/rune-modules/src/process.rs index 2157df549..6b02b9646 100644 --- a/crates/rune-modules/src/process.rs +++ b/crates/rune-modules/src/process.rs @@ -44,12 +44,12 @@ pub fn module(_stdio: bool) -> Result { module.ty::()?; module.function(["Command", "new"], Command::new)?; - module.inst_fn("spawn", Command::spawn)?; - module.inst_fn("arg", Command::arg)?; - module.inst_fn("args", Command::args)?; - module.async_inst_fn("wait_with_output", Child::wait_with_output)?; - module.inst_fn(Protocol::STRING_DISPLAY, ExitStatus::display)?; - module.inst_fn("code", ExitStatus::code)?; + module.associated_function("spawn", Command::spawn)?; + module.associated_function("arg", Command::arg)?; + module.associated_function("args", Command::args)?; + module.associated_function("wait_with_output", Child::wait_with_output)?; + module.associated_function(Protocol::STRING_DISPLAY, ExitStatus::display)?; + module.associated_function("code", ExitStatus::code)?; Ok(module) } diff --git a/crates/rune-modules/src/rand.rs b/crates/rune-modules/src/rand.rs index 5857b6e2e..fd5428402 100644 --- a/crates/rune-modules/src/rand.rs +++ b/crates/rune-modules/src/rand.rs @@ -42,14 +42,14 @@ pub fn module(_stdio: bool) -> Result { module.ty::()?; module.function(["WyRand", "new"], WyRand::new)?; module.function(["WyRand", "new_seed"], WyRand::new_seed)?; - module.inst_fn("int", WyRand::int)?; - module.inst_fn("int_range", WyRand::int_range)?; + module.associated_function("int", WyRand::int)?; + module.associated_function("int_range", WyRand::int_range)?; module.ty::()?; module.function(["Pcg64", "new"], Pcg64::new)?; module.function(["Pcg64", "new_seed"], Pcg64::new_seed)?; - module.inst_fn("int", Pcg64::int)?; - module.inst_fn("int_range", Pcg64::int_range)?; + module.associated_function("int", Pcg64::int)?; + module.associated_function("int_range", Pcg64::int_range)?; module.function(["int"], int)?; module.function(["int_range"], int_range)?; diff --git a/crates/rune-wasm/src/http.rs b/crates/rune-wasm/src/http.rs index c582c3f35..07a25af2b 100644 --- a/crates/rune-wasm/src/http.rs +++ b/crates/rune-wasm/src/http.rs @@ -7,8 +7,8 @@ pub fn module() -> Result { let mut module = Module::with_crate("http"); module.ty::()?; module.ty::()?; - module.async_function(["get"], get)?; - module.async_inst_fn("text", Response::text)?; + module.function(["get"], get)?; + module.associated_function("text", Response::text)?; Ok(module) } diff --git a/crates/rune-wasm/src/time.rs b/crates/rune-wasm/src/time.rs index f616e2913..2e323f22f 100644 --- a/crates/rune-wasm/src/time.rs +++ b/crates/rune-wasm/src/time.rs @@ -14,7 +14,7 @@ pub fn module() -> Result { let mut module = Module::with_crate("time"); module.ty::()?; module.function(["Duration", "from_secs"], Duration::from_secs)?; - module.async_function(["delay_for"], delay_for)?; + module.function(["delay_for"], delay_for)?; Ok(module) } diff --git a/crates/rune/.gitignore b/crates/rune/.gitignore new file mode 100644 index 000000000..2d37847ca --- /dev/null +++ b/crates/rune/.gitignore @@ -0,0 +1 @@ +/wip/ diff --git a/crates/rune/Cargo.toml b/crates/rune/Cargo.toml index cc85d96dd..ce1175b3c 100644 --- a/crates/rune/Cargo.toml +++ b/crates/rune/Cargo.toml @@ -78,6 +78,7 @@ tokio = { version = "1.28.1", features = ["full"] } static_assertions = "1.1.0" checkers = "0.6.3" futures-executor = "0.3.28" +trybuild = "1.0.80" [package.metadata.docs.rs] all-features = true diff --git a/crates/rune/src/compile/context.rs b/crates/rune/src/compile/context.rs index 198fbaa83..1aad4fa2d 100644 --- a/crates/rune/src/compile/context.rs +++ b/crates/rune/src/compile/context.rs @@ -529,7 +529,7 @@ impl Context { } self.constants.insert( - Hash::instance_function(ty.hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(ty.hash, Protocol::INTO_TYPE_NAME), ConstValue::String(ty.item.to_string()), ); @@ -556,7 +556,7 @@ impl Context { let hash = Hash::type_hash(&item); self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(item.to_string()), ); @@ -679,7 +679,7 @@ impl Context { .with_function_parameters(assoc.name.function_parameters); self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(item.to_string()), ); @@ -758,7 +758,7 @@ impl Context { })?; self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(item.to_string()), ); diff --git a/crates/rune/src/compile/meta.rs b/crates/rune/src/compile/meta.rs index 547683fb6..4c4873b30 100644 --- a/crates/rune/src/compile/meta.rs +++ b/crates/rune/src/compile/meta.rs @@ -343,14 +343,14 @@ impl AssociatedKind { /// Convert the kind into a hash function. pub(crate) fn hash(&self, instance_type: Hash) -> Hash { match self { - Self::Protocol(protocol) => Hash::instance_function(instance_type, protocol.hash), + Self::Protocol(protocol) => Hash::associated_function(instance_type, protocol.hash), Self::IndexFn(protocol, index) => { - Hash::index_fn(*protocol, instance_type, Hash::index(*index)) + Hash::index_function(*protocol, instance_type, Hash::index(*index)) } Self::FieldFn(protocol, field) => { - Hash::field_fn(*protocol, instance_type, field.as_ref()) + Hash::field_function(*protocol, instance_type, field.as_ref()) } - Self::Instance(name) => Hash::instance_function(instance_type, name.as_ref()), + Self::Instance(name) => Hash::associated_function(instance_type, name.as_ref()), } } } diff --git a/crates/rune/src/compile/unit_builder.rs b/crates/rune/src/compile/unit_builder.rs index 32247c745..430aad531 100644 --- a/crates/rune/src/compile/unit_builder.rs +++ b/crates/rune/src/compile/unit_builder.rs @@ -291,7 +291,7 @@ impl UnitBuilder { }); self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(rtti.item.to_string()), ); @@ -335,7 +335,7 @@ impl UnitBuilder { } self.constants.insert( - Hash::instance_function(meta.hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(meta.hash, Protocol::INTO_TYPE_NAME), ConstValue::String(signature.path.to_string()), ); @@ -377,7 +377,7 @@ impl UnitBuilder { } self.constants.insert( - Hash::instance_function(meta.hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(meta.hash, Protocol::INTO_TYPE_NAME), ConstValue::String(signature.path.to_string()), ); @@ -392,7 +392,7 @@ impl UnitBuilder { }); self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(rtti.item.to_string()), ); @@ -500,7 +500,7 @@ impl UnitBuilder { } meta::Kind::Enum { .. } => { self.constants.insert( - Hash::instance_function(meta.hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(meta.hash, Protocol::INTO_TYPE_NAME), ConstValue::String(pool.item(meta.item_meta.item).to_string()), ); } @@ -555,7 +555,7 @@ impl UnitBuilder { } self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(signature.path.to_string()), ); @@ -600,7 +600,7 @@ impl UnitBuilder { tracing::trace!("instance fn: {}", item); let offset = self.instructions.len(); - let instance_fn = Hash::instance_function(type_hash, name); + let instance_fn = Hash::associated_function(type_hash, name); let hash = Hash::type_hash(item); let info = UnitFn::Offset { offset, call, args }; @@ -625,7 +625,7 @@ impl UnitBuilder { } self.constants.insert( - Hash::instance_function(hash, Protocol::INTO_TYPE_NAME), + Hash::associated_function(hash, Protocol::INTO_TYPE_NAME), ConstValue::String(signature.path.to_string()), ); diff --git a/crates/rune/src/module.rs b/crates/rune/src/module.rs index 498fde838..c1695b02b 100644 --- a/crates/rune/src/module.rs +++ b/crates/rune/src/module.rs @@ -23,7 +23,7 @@ pub(crate) use self::function_meta::{AssociatedFunctionName, ToFieldFunction, To #[doc(hidden)] pub use self::function_meta::{FunctionMetaData, FunctionMetaKind, MacroMetaData, MacroMetaKind}; -pub use self::function_traits::{AsyncFunction, AsyncInstFn, Function, InstFn}; +pub use self::function_traits::{Async, Function, FunctionKind, InstanceFunction, Plain}; #[doc(hidden)] pub use self::module::Module; @@ -83,7 +83,7 @@ impl InternalEnum { constructor: C, ) -> ItemMut<'_> where - C: Function, + C: Function, { let constructor: Arc = Arc::new(move |stack, args| constructor.fn_call(stack, args)); @@ -242,9 +242,7 @@ pub(crate) struct ModuleConstant { /// This is returned by methods which insert meta items, such as: /// * [`Module::raw_fn`]. /// * [`Module::function`]. -/// * [`Module::async_function`]. -/// * [`Module::inst_fn`]. -/// * [`Module::async_inst_fn`]. +/// * [`Module::associated_function`]. /// /// While this is also returned by `*_meta` inserting functions, it is instead /// recommended that you make use of the appropriate macro to capture doc @@ -331,7 +329,7 @@ where /// Register a constructor method for the current variant. pub fn constructor(self, constructor: F) -> Result where - F: Function, + F: Function, { if self.constructor.is_some() { return Err(ContextError::VariantConstructorConflict { diff --git a/crates/rune/src/module/function_meta.rs b/crates/rune/src/module/function_meta.rs index 62fd09ff4..25b8501f6 100644 --- a/crates/rune/src/module/function_meta.rs +++ b/crates/rune/src/module/function_meta.rs @@ -1,5 +1,4 @@ -#[cfg(feature = "doc")] -use core::future::Future; +use core::marker::PhantomData; use crate::no_std::borrow::Cow; use crate::no_std::prelude::*; @@ -8,7 +7,7 @@ use crate::no_std::sync::Arc; use crate::compile::{self, meta, IntoComponent, ItemBuf, Named}; use crate::hash::Hash; use crate::macros::{MacroContext, TokenStream}; -use crate::module::{AssociatedKey, AsyncFunction, AsyncInstFn, Function, InstFn}; +use crate::module::{AssociatedKey, Function, FunctionKind, InstanceFunction}; use crate::runtime::{ FullTypeOf, FunctionHandler, MacroHandler, MaybeTypeOf, Protocol, TypeInfo, TypeOf, }; @@ -49,11 +48,11 @@ pub type MacroMeta = fn() -> MacroMetaData; /// Runtime data for a function. #[derive(Clone)] pub struct FunctionData { - #[cfg(feature = "doc")] - pub(crate) is_async: bool, pub(crate) item: ItemBuf, pub(crate) handler: Arc, #[cfg(feature = "doc")] + pub(crate) is_async: bool, + #[cfg(feature = "doc")] pub(crate) args: Option, #[cfg(feature = "doc")] pub(crate) return_type: Option, @@ -63,54 +62,26 @@ pub struct FunctionData { impl FunctionData { #[inline] - pub(crate) fn new(name: N, f: F) -> Self + pub(crate) fn new(name: N, f: F) -> Self where - F: Function, + F: Function, F::Return: MaybeTypeOf, N: IntoIterator, N::Item: IntoComponent, - A: IterFunctionArgs, + A: FunctionArgs, + K: FunctionKind, { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - Self { - #[cfg(feature = "doc")] - is_async: false, item: ItemBuf::with_item(name), handler: Arc::new(move |stack, args| f.fn_call(stack, args)), #[cfg(feature = "doc")] - args: Some(F::args()), - #[cfg(feature = "doc")] - return_type: F::Return::maybe_type_of(), - #[cfg(feature = "doc")] - argument_types: argument_types.into(), - } - } - - #[inline] - pub(crate) fn new_async(name: N, f: F) -> Self - where - F: AsyncFunction, - F::Output: MaybeTypeOf, - N: IntoIterator, - N::Item: IntoComponent, - A: IterFunctionArgs, - { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - - Self { - #[cfg(feature = "doc")] - is_async: true, - item: ItemBuf::with_item(name), - handler: Arc::new(move |stack, args| f.fn_call(stack, args)), + is_async: K::is_async(), #[cfg(feature = "doc")] args: Some(F::args()), #[cfg(feature = "doc")] - return_type: F::Output::maybe_type_of(), + return_type: F::Return::maybe_type_of(), #[cfg(feature = "doc")] - argument_types: argument_types.into(), + argument_types: A::into_box(), } } } @@ -204,12 +175,12 @@ impl ToFieldFunction for &'static str { /// Runtime data for an associated function. #[derive(Clone)] pub struct AssociatedFunctionData { + pub(crate) name: AssociatedFunctionName, + pub(crate) handler: Arc, pub(crate) container: FullTypeOf, pub(crate) container_type_info: TypeInfo, #[cfg(feature = "doc")] pub(crate) is_async: bool, - pub(crate) name: AssociatedFunctionName, - pub(crate) handler: Arc, #[cfg(feature = "doc")] pub(crate) args: Option, #[cfg(feature = "doc")] @@ -220,108 +191,26 @@ pub struct AssociatedFunctionData { impl AssociatedFunctionData { #[inline] - pub(crate) fn new(name: AssociatedFunctionName, f: F) -> Self + pub(crate) fn new(name: AssociatedFunctionName, f: F) -> Self where - F: InstFn, + F: InstanceFunction, F::Return: MaybeTypeOf, - A: IterFunctionArgs, + A: FunctionArgs, + K: FunctionKind, { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - Self { - container: F::Inst::type_of(), - container_type_info: F::Inst::type_info(), - #[cfg(feature = "doc")] - is_async: false, name, handler: Arc::new(move |stack, args| f.fn_call(stack, args)), + container: F::Instance::type_of(), + container_type_info: F::Instance::type_info(), #[cfg(feature = "doc")] - args: Some(F::args()), - #[cfg(feature = "doc")] - return_type: F::Return::maybe_type_of(), - #[cfg(feature = "doc")] - argument_types: argument_types.into(), - } - } - - #[inline] - pub(crate) fn new_with(name: AssociatedFunctionName, f: F) -> Self - where - T: TypeOf + Named, - F: Function, - F::Return: MaybeTypeOf, - A: IterFunctionArgs, - { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - - Self { - container: T::type_of(), - container_type_info: T::type_info(), - #[cfg(feature = "doc")] - is_async: false, - name, - handler: Arc::new(move |stack, args| f.fn_call(stack, args)), + is_async: K::is_async(), #[cfg(feature = "doc")] args: Some(F::args()), #[cfg(feature = "doc")] return_type: F::Return::maybe_type_of(), #[cfg(feature = "doc")] - argument_types: argument_types.into(), - } - } - - #[inline] - pub(crate) fn new_async(name: AssociatedFunctionName, f: F) -> Self - where - F: AsyncInstFn, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, - { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - - Self { - container: F::Inst::type_of(), - container_type_info: F::Inst::type_info(), - #[cfg(feature = "doc")] - is_async: true, - name, - handler: Arc::new(move |stack, args| f.fn_call(stack, args)), - #[cfg(feature = "doc")] - args: Some(F::args()), - #[cfg(feature = "doc")] - return_type: ::Output::maybe_type_of(), - #[cfg(feature = "doc")] - argument_types: argument_types.into(), - } - } - - #[inline] - pub(crate) fn new_async_with(name: AssociatedFunctionName, f: F) -> Self - where - T: TypeOf + Named, - F: AsyncFunction, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, - { - let mut argument_types = Vec::with_capacity(A::len()); - A::iter_args(|ty| argument_types.push(ty)); - - Self { - container: T::type_of(), - container_type_info: T::type_info(), - #[cfg(feature = "doc")] - is_async: true, - name, - handler: Arc::new(move |stack, args| f.fn_call(stack, args)), - #[cfg(feature = "doc")] - args: Some(F::args()), - #[cfg(feature = "doc")] - return_type: ::Output::maybe_type_of(), - #[cfg(feature = "doc")] - argument_types: argument_types.into(), + argument_types: A::into_box(), } } @@ -351,84 +240,79 @@ pub enum FunctionMetaKind { impl FunctionMetaKind { #[doc(hidden)] #[inline] - pub fn function(name: N, f: F) -> Self + pub fn function(name: N, f: F) -> FunctionBuilder where - N: IntoIterator, - N::Item: IntoComponent, - F: Function, + F: Function, F::Return: MaybeTypeOf, - A: IterFunctionArgs, + A: FunctionArgs, + K: FunctionKind, { - Self::Function(FunctionData::new(name, f)) + FunctionBuilder { + name, + f, + _marker: PhantomData, + } } #[doc(hidden)] #[inline] - pub fn function_with(name: N, f: F) -> Self + pub fn instance(name: N, f: F) -> Self where - T: TypeOf + Named, N: ToInstance, - F: Function, + F: InstanceFunction, F::Return: MaybeTypeOf, - A: IterFunctionArgs, + A: FunctionArgs, + K: FunctionKind, { - Self::AssociatedFunction(AssociatedFunctionData::new_with::( - name.to_instance(), - f, - )) + Self::AssociatedFunction(AssociatedFunctionData::new(name.to_instance(), f)) } +} +#[doc(hidden)] +pub struct FunctionBuilder { + name: N, + f: F, + _marker: PhantomData<(A, K)>, +} + +impl FunctionBuilder +where + F: Function, + F::Return: MaybeTypeOf, + A: FunctionArgs, + K: FunctionKind, +{ #[doc(hidden)] #[inline] - pub fn async_function(name: N, f: F) -> Self + pub fn build(self) -> FunctionMetaKind where N: IntoIterator, N::Item: IntoComponent, - F: AsyncFunction, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, { - Self::Function(FunctionData::new_async(name, f)) + FunctionMetaKind::Function(FunctionData::new(self.name, self.f)) } #[doc(hidden)] #[inline] - pub fn async_function_with(name: N, f: F) -> Self + pub fn build_associated(self) -> FunctionMetaKind where - T: TypeOf + Named, N: ToInstance, - F: AsyncFunction, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, - { - Self::AssociatedFunction(AssociatedFunctionData::new_async_with::( - name.to_instance(), - f, - )) - } - - #[doc(hidden)] - #[inline] - pub fn instance(name: N, f: F) -> Self - where - N: ToInstance, - F: InstFn, - F::Return: MaybeTypeOf, - A: IterFunctionArgs, - { - Self::AssociatedFunction(AssociatedFunctionData::new(name.to_instance(), f)) - } - - #[doc(hidden)] - #[inline] - pub fn async_instance(name: N, f: F) -> Self - where - N: ToInstance, - F: AsyncInstFn, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, + T: TypeOf + Named, { - Self::AssociatedFunction(AssociatedFunctionData::new_async(name.to_instance(), f)) + FunctionMetaKind::AssociatedFunction(AssociatedFunctionData { + name: self.name.to_instance(), + handler: Arc::new(move |stack, args| self.f.fn_call(stack, args)), + container: T::type_of(), + container_type_info: T::type_info(), + #[cfg(feature = "doc")] + is_async: K::is_async(), + #[cfg(feature = "doc")] + args: Some(F::args()), + #[cfg(feature = "doc")] + return_type: F::Return::maybe_type_of(), + #[cfg(feature = "doc")] + argument_types: A::into_box(), + }) } } @@ -493,32 +377,21 @@ pub struct FunctionMetaData { /// Trait implement allowing the collection of function argument types. #[doc(hidden)] -pub trait IterFunctionArgs { - /// The number of arguments being passed in. - fn len() -> usize; - - /// Iterate over arguments providing their full type information in the - /// process. +pub trait FunctionArgs { #[doc(hidden)] - fn iter_args(receiver: Receiver) - where - Receiver: FnMut(Option); + fn into_box() -> Box<[Option]>; } macro_rules! iter_function_args { ($count:expr $(, $ty:ident $var:ident $num:expr)*) => { - impl<$($ty,)*> IterFunctionArgs for ($($ty,)*) + impl<$($ty,)*> FunctionArgs for ($($ty,)*) where $($ty: MaybeTypeOf,)* { #[inline] - fn len() -> usize { - $count - } - - #[inline] - fn iter_args(#[allow(unused)] mut receiver: Receiver) where Receiver: FnMut(Option) { - $(receiver(<$ty>::maybe_type_of());)* + #[doc(hidden)] + fn into_box() -> Box<[Option]> { + vec![$(<$ty>::maybe_type_of(),)*].into() } } } diff --git a/crates/rune/src/module/function_traits.rs b/crates/rune/src/module/function_traits.rs index 29e8e9bc5..eead2d8cb 100644 --- a/crates/rune/src/module/function_traits.rs +++ b/crates/rune/src/module/function_traits.rs @@ -34,7 +34,7 @@ macro_rules! drop_stack_guards { // Expand to instance variable bindings. macro_rules! unsafe_inst_vars { ($inst:ident, $count:expr, $($ty:ty, $var:ident, $num:expr,)*) => { - let $inst = vm_try!(Inst::from_value($inst).with_error(|| VmErrorKind::BadArgument { + let $inst = vm_try!(Instance::from_value($inst).with_error(|| VmErrorKind::BadArgument { arg: 0, })); @@ -46,49 +46,38 @@ macro_rules! unsafe_inst_vars { }; } -/// Trait used to provide the [function][crate::module::Module::function] -/// function. -pub trait Function: 'static + Send + Sync { - /// The return type of the function. - #[doc(hidden)] - type Return; - - /// Get the number of arguments. - #[doc(hidden)] - fn args() -> usize; - - /// Perform the vm call. - #[doc(hidden)] - fn fn_call(&self, stack: &mut Stack, args: usize) -> VmResult<()>; +/// Denotes the kind of a function, allowing the [`Function`] trait to be +/// implemented separately for plain and async functions. +pub trait FunctionKind { + /// Indicates if the function is async. + fn is_async() -> bool; } -/// Trait used to provide the -/// [async_function][crate::module::Module::async_function] function. -pub trait AsyncFunction: 'static + Send + Sync { - /// The return type of the function. - #[doc(hidden)] - type Return: Future; +/// Marker for plain functions. +#[non_exhaustive] +pub struct Plain; - /// The output produces by the future. - #[doc(hidden)] - type Output; +impl FunctionKind for Plain { + #[inline] + fn is_async() -> bool { + false + } +} - /// Get the number of arguments. - #[doc(hidden)] - fn args() -> usize; +/// Marker for async functions. +#[non_exhaustive] +pub struct Async; - /// Perform the vm call. - #[doc(hidden)] - fn fn_call(&self, stack: &mut Stack, args: usize) -> VmResult<()>; +impl FunctionKind for Async { + #[inline] + fn is_async() -> bool { + true + } } -/// Trait used to provide the [inst_fn][crate::module::Module::inst_fn] +/// Trait used to provide the [function][crate::module::Module::function] /// function. -pub trait InstFn: 'static + Send + Sync { - /// The type of the instance. - #[doc(hidden)] - type Inst: TypeOf; - +pub trait Function: 'static + Send + Sync { /// The return type of the function. #[doc(hidden)] type Return; @@ -102,20 +91,17 @@ pub trait InstFn: 'static + Send + Sync { fn fn_call(&self, stack: &mut Stack, args: usize) -> VmResult<()>; } -/// Trait used to provide the -/// [async_inst_fn][crate::module::Module::async_inst_fn] function. -pub trait AsyncInstFn: 'static + Send + Sync { +/// Trait used to provide the [`associated_function`] function. +/// +/// [`associated_function`]: crate::module::Module::associated_function +pub trait InstanceFunction: 'static + Send + Sync { /// The type of the instance. #[doc(hidden)] - type Inst: TypeOf; + type Instance: TypeOf; /// The return type of the function. #[doc(hidden)] - type Return: Future; - - /// The output value of the async function. - #[doc(hidden)] - type Output; + type Return; /// Get the number of arguments. #[doc(hidden)] @@ -128,7 +114,7 @@ pub trait AsyncInstFn: 'static + Send + Sync { macro_rules! impl_register { ($count:expr $(, $ty:ident $var:ident $num:expr)*) => { - impl Function<($($ty,)*)> for T + impl Function<($($ty,)*), Plain> for T where T: 'static + Send + Sync + Fn($($ty,)*) -> U, U: ToValue, @@ -163,15 +149,14 @@ macro_rules! impl_register { } } - impl AsyncFunction<($($ty,)*)> for T + impl Function<($($ty,)*), Async> for T where T: 'static + Send + Sync + Fn($($ty,)*) -> U, U: 'static + Future, U::Output: ToValue, $($ty: 'static + UnsafeFromValue,)* { - type Return = U; - type Output = U::Output; + type Return = U::Output; fn args() -> usize { $count @@ -204,14 +189,14 @@ macro_rules! impl_register { } } - impl InstFn<(Inst, $($ty,)*)> for T + impl InstanceFunction<(Instance, $($ty,)*), Plain> for T where - T: 'static + Send + Sync + Fn(Inst $(, $ty)*) -> U, + T: 'static + Send + Sync + Fn(Instance $(, $ty)*) -> U, U: ToValue, - Inst: UnsafeFromValue + TypeOf, + Instance: UnsafeFromValue + TypeOf, $($ty: UnsafeFromValue,)* { - type Inst = Inst; + type Instance = Instance; type Return = U; #[inline] @@ -231,7 +216,7 @@ macro_rules! impl_register { #[allow(unused)] let ret = unsafe { unsafe_inst_vars!(inst, $count, $($ty, $var, $num,)*); - let ret = self(Inst::unsafe_coerce(inst.0), $(<$ty>::unsafe_coerce($var.0),)*); + let ret = self(Instance::unsafe_coerce(inst.0), $(<$ty>::unsafe_coerce($var.0),)*); drop_stack_guards!(inst, $($var),*); ret }; @@ -242,17 +227,16 @@ macro_rules! impl_register { } } - impl AsyncInstFn<(Inst, $($ty,)*)> for T + impl InstanceFunction<(Instance, $($ty,)*), Async> for T where - T: 'static + Send + Sync + Fn(Inst $(, $ty)*) -> U, + T: 'static + Send + Sync + Fn(Instance $(, $ty)*) -> U, U: 'static + Future, U::Output: ToValue, - Inst: UnsafeFromValue + TypeOf, + Instance: UnsafeFromValue + TypeOf, $($ty: UnsafeFromValue,)* { - type Inst = Inst; - type Return = U; - type Output = U::Output; + type Instance = Instance; + type Return = U::Output; #[inline] fn args() -> usize { @@ -270,7 +254,7 @@ macro_rules! impl_register { #[allow(unused)] let ret = unsafe { unsafe_inst_vars!(inst, $count, $($ty, $var, $num,)*); - let fut = self(Inst::unsafe_coerce(inst.0), $(<$ty>::unsafe_coerce($var.0),)*); + let fut = self(Instance::unsafe_coerce(inst.0), $(<$ty>::unsafe_coerce($var.0),)*); runtime::Future::new(async move { let output = fut.await; diff --git a/crates/rune/src/module/module.rs b/crates/rune/src/module/module.rs index c7778fb6c..63186ae52 100644 --- a/crates/rune/src/module/module.rs +++ b/crates/rune/src/module/module.rs @@ -7,13 +7,13 @@ use crate::no_std::sync::Arc; use crate::compile::{self, meta, ContextError, Docs, IntoComponent, ItemBuf, Named}; use crate::macros::{MacroContext, TokenStream}; use crate::module::function_meta::{ - AssociatedFunctionData, AssociatedFunctionName, FunctionData, FunctionMeta, FunctionMetaKind, - IterFunctionArgs, MacroMeta, MacroMetaKind, ToFieldFunction, ToInstance, + AssociatedFunctionData, AssociatedFunctionName, FunctionArgs, FunctionData, FunctionMeta, + FunctionMetaKind, MacroMeta, MacroMetaKind, ToFieldFunction, ToInstance, }; use crate::module::{ - AssociatedKey, AsyncFunction, AsyncInstFn, EnumMut, Function, InstFn, InstallWith, + AssociatedKey, Async, EnumMut, Function, FunctionKind, InstallWith, InstanceFunction, InternalEnum, InternalEnumMut, ItemMut, ModuleAssociated, ModuleConstant, ModuleFunction, - ModuleMacro, ModuleType, TypeMut, TypeSpecification, UnitType, VariantMut, + ModuleMacro, ModuleType, Plain, TypeMut, TypeSpecification, UnitType, VariantMut, }; use crate::runtime::{ ConstValue, FromValue, GeneratorState, MacroHandler, MaybeTypeOf, Protocol, Stack, ToValue, @@ -150,7 +150,7 @@ impl Module { /// // Register `len` without registering a type. /// let mut module = Module::default(); /// // Note: cannot do this until we have registered a type. - /// module.inst_fn("len", MyBytes::len)?; + /// module.associated_function("len", MyBytes::len)?; /// /// let mut context = rune::Context::new(); /// assert!(context.install(module).is_err()); @@ -159,7 +159,7 @@ impl Module { /// let mut module = Module::default(); /// /// module.ty::()?; - /// module.inst_fn("len", MyBytes::len)?; + /// module.associated_function("len", MyBytes::len)?; /// /// let mut context = Context::new(); /// assert!(context.install(module).is_ok()); @@ -234,7 +234,7 @@ impl Module { /// /// This is typically not used directly, but is used automatically with the /// [Any][crate::Any] derive. - #[deprecated = "Use type_meta() instead"] + #[deprecated = "Use type_meta::().make_struct(fields) instead"] pub fn struct_meta(&mut self, fields: &'static [&'static str]) -> Result<(), ContextError> where T: Named + TypeOf, @@ -245,7 +245,7 @@ impl Module { /// Register enum metadata for the given type `T`. This allows an enum to be /// used in limited ways in Rune. - #[deprecated = "Use type_meta().make_enum() instead"] + #[deprecated = "Use type_meta::().make_enum(variants) instead"] #[doc(hidden)] pub fn enum_meta( &mut self, @@ -302,7 +302,7 @@ impl Module { constructor: F, ) -> Result<(), ContextError> where - F: Function, + F: Function, F::Return: Named + TypeOf, { self.variant_meta::(index)? @@ -740,26 +740,8 @@ impl Module { /// module.function(["add_ten"], add_ten)?.docs(["Adds 10 to any integer passed in."]); /// # Ok::<_, rune::Error>(()) /// ``` - pub fn function(&mut self, name: N, f: F) -> Result, ContextError> - where - F: Function, - F::Return: MaybeTypeOf, - N: IntoIterator, - N::Item: IntoComponent, - A: IterFunctionArgs, - { - self.function_inner(FunctionData::new(name, f), Docs::EMPTY) - } - - /// Register an asynchronous function. /// - /// If possible, [`Module::function_meta`] should be used since it includes - /// more useful information about the function. - /// - /// This returns a [`ItemMut`], which is a handle that can be used to associate more metadata - /// with the inserted item. - /// - /// # Examples + /// Asynchronous function: /// /// ``` /// use rune::{Any, Module}; @@ -776,19 +758,33 @@ impl Module { /// /// let mut module = Module::default(); /// - /// module.async_function(["download_quote"], download_quote)? + /// module.function(["download_quote"], download_quote)? /// .docs(["Download a random quote from the internet."]); /// # Ok::<_, rune::Error>(()) /// ``` + pub fn function(&mut self, name: N, f: F) -> Result, ContextError> + where + F: Function, + F::Return: MaybeTypeOf, + N: IntoIterator, + N::Item: IntoComponent, + A: FunctionArgs, + K: FunctionKind, + { + self.function_inner(FunctionData::new(name, f), Docs::EMPTY) + } + + /// See [`Module::function`]. + #[deprecated = "Use Module::function() instead"] pub fn async_function(&mut self, name: N, f: F) -> Result, ContextError> where - F: AsyncFunction, - F::Output: MaybeTypeOf, + F: Function, + F::Return: MaybeTypeOf, N: IntoIterator, N::Item: IntoComponent, - A: IterFunctionArgs, + A: FunctionArgs, { - self.function_inner(FunctionData::new_async(name, f), Docs::EMPTY) + self.function_inner(FunctionData::new(name, f), Docs::EMPTY) } /// Register an instance function. @@ -828,32 +824,12 @@ impl Module { /// module.function(["MyBytes", "new"], MyBytes::new)? /// .docs(["Construct a new empty bytes container."]); /// - /// module.inst_fn("len", MyBytes::len)? + /// module.associated_function("len", MyBytes::len)? /// .docs(["Get the number of bytes."]); /// # Ok::<_, rune::Error>(()) /// ``` - pub fn inst_fn(&mut self, name: N, f: F) -> Result, ContextError> - where - N: ToInstance, - F: InstFn, - F::Return: MaybeTypeOf, - A: IterFunctionArgs, - { - self.assoc_fn( - AssociatedFunctionData::new(name.to_instance(), f), - Docs::EMPTY, - ) - } - - /// Register an asynchronous instance function. - /// - /// If possible, [`Module::function_meta`] should be used since it includes - /// more useful information about the function. /// - /// This returns a [`ItemMut`], which is a handle that can be used to associate more metadata - /// with the inserted item. - /// - /// # Examples + /// Asynchronous function: /// /// ``` /// use std::sync::atomic::AtomicU32; @@ -881,28 +857,59 @@ impl Module { /// let mut module = Module::default(); /// /// module.ty::()?; - /// module.async_inst_fn("download", Client::download)? + /// module.associated_function("download", Client::download)? /// .docs(["Download a thing."]); /// # Ok::<_, rune::Error>(()) /// ``` - pub fn async_inst_fn(&mut self, name: N, f: F) -> Result, ContextError> + pub fn associated_function( + &mut self, + name: N, + f: F, + ) -> Result, ContextError> where N: ToInstance, - F: AsyncInstFn, - F::Output: MaybeTypeOf, - A: IterFunctionArgs, + F: InstanceFunction, + F::Return: MaybeTypeOf, + A: FunctionArgs, + K: FunctionKind, { self.assoc_fn( - AssociatedFunctionData::new_async(name.to_instance(), f), + AssociatedFunctionData::new(name.to_instance(), f), Docs::EMPTY, ) } + /// See [`Module::associated_function`]. + #[deprecated = "Use Module::associated_function() instead"] + #[inline] + pub fn inst_fn(&mut self, name: N, f: F) -> Result, ContextError> + where + N: ToInstance, + F: InstanceFunction, + F::Return: MaybeTypeOf, + A: FunctionArgs, + K: FunctionKind, + { + self.associated_function(name, f) + } + + /// See [`Module::associated_function`]. + #[deprecated = "Use Module::associated_function() instead"] + pub fn async_inst_fn(&mut self, name: N, f: F) -> Result, ContextError> + where + N: ToInstance, + F: InstanceFunction, + F::Return: MaybeTypeOf, + A: FunctionArgs, + { + self.associated_function(name, f) + } + /// Install a protocol function that interacts with the given field. /// /// This returns a [`ItemMut`], which is a handle that can be used to /// associate more metadata with the inserted item. - pub fn field_fn( + pub fn field_function( &mut self, protocol: Protocol, name: N, @@ -910,9 +917,9 @@ impl Module { ) -> Result, ContextError> where N: ToFieldFunction, - F: InstFn, + F: InstanceFunction, F::Return: MaybeTypeOf, - A: IterFunctionArgs, + A: FunctionArgs, { self.assoc_fn( AssociatedFunctionData::new(name.to_field_function(protocol), f), @@ -920,25 +927,60 @@ impl Module { ) } + /// See [`Module::field_function`]. + #[deprecated = "Use Module::field_function() instead"] + #[inline] + pub fn field_fn( + &mut self, + protocol: Protocol, + name: N, + f: F, + ) -> Result, ContextError> + where + N: ToFieldFunction, + F: InstanceFunction, + F::Return: MaybeTypeOf, + A: FunctionArgs, + { + self.field_function(protocol, name, f) + } + /// Install a protocol function that interacts with the given index. /// /// An index can either be a field inside a tuple, or a variant inside of an /// enum as configured with [Module::enum_meta]. - pub fn index_fn( + pub fn index_function( &mut self, protocol: Protocol, index: usize, f: F, ) -> Result, ContextError> where - F: InstFn, + F: InstanceFunction, F::Return: MaybeTypeOf, - A: IterFunctionArgs, + A: FunctionArgs, { let name = AssociatedFunctionName::index(protocol, index); self.assoc_fn(AssociatedFunctionData::new(name, f), Docs::EMPTY) } + /// See [`Module::index_function`]. + #[deprecated = "Use Module::index_function() instead"] + #[inline] + pub fn index_fn( + &mut self, + protocol: Protocol, + index: usize, + f: F, + ) -> Result, ContextError> + where + F: InstanceFunction, + F::Return: MaybeTypeOf, + A: FunctionArgs, + { + self.index_function(protocol, index, f) + } + /// Register a raw function which interacts directly with the virtual /// machine. /// diff --git a/crates/rune/src/modules/any.rs b/crates/rune/src/modules/any.rs index 95e18c0c3..9aca04895 100644 --- a/crates/rune/src/modules/any.rs +++ b/crates/rune/src/modules/any.rs @@ -16,7 +16,7 @@ pub fn module() -> Result { .docs(["Represents a type in the Rune type system."]); module.function_meta(type_of_val)?; module.function_meta(type_name_of_val)?; - module.inst_fn(Protocol::STRING_DISPLAY, format_type)?; + module.associated_function(Protocol::STRING_DISPLAY, format_type)?; Ok(module) } diff --git a/crates/rune/src/modules/bytes.rs b/crates/rune/src/modules/bytes.rs index 7b17e32b5..daa12fb87 100644 --- a/crates/rune/src/modules/bytes.rs +++ b/crates/rune/src/modules/bytes.rs @@ -18,12 +18,12 @@ pub fn module() -> Result { module.function_meta(Bytes::__pop__meta)?; module.function_meta(Bytes::__last__meta)?; - module.inst_fn("len", Bytes::len)?; - module.inst_fn("capacity", Bytes::capacity)?; - module.inst_fn("clear", Bytes::clear)?; - module.inst_fn("reserve", Bytes::reserve)?; - module.inst_fn("reserve_exact", Bytes::reserve_exact)?; - module.inst_fn("clone", Bytes::clone)?; - module.inst_fn("shrink_to_fit", Bytes::shrink_to_fit)?; + module.associated_function("len", Bytes::len)?; + module.associated_function("capacity", Bytes::capacity)?; + module.associated_function("clear", Bytes::clear)?; + module.associated_function("reserve", Bytes::reserve)?; + module.associated_function("reserve_exact", Bytes::reserve_exact)?; + module.associated_function("clone", Bytes::clone)?; + module.associated_function("shrink_to_fit", Bytes::shrink_to_fit)?; Ok(module) } diff --git a/crates/rune/src/modules/char.rs b/crates/rune/src/modules/char.rs index c26256428..03fea5c8b 100644 --- a/crates/rune/src/modules/char.rs +++ b/crates/rune/src/modules/char.rs @@ -16,12 +16,12 @@ pub fn module() -> Result { module.function_meta(to_int)?; module.function_meta(is_alphabetic)?; module.function_meta(is_alphanumeric)?; - module.inst_fn("is_control", char::is_control)?; - module.inst_fn("is_lowercase", char::is_lowercase)?; - module.inst_fn("is_numeric", char::is_numeric)?; - module.inst_fn("is_uppercase", char::is_uppercase)?; - module.inst_fn("is_whitespace", char::is_whitespace)?; - module.inst_fn("to_digit", char::to_digit)?; + module.associated_function("is_control", char::is_control)?; + module.associated_function("is_lowercase", char::is_lowercase)?; + module.associated_function("is_numeric", char::is_numeric)?; + module.associated_function("is_uppercase", char::is_uppercase)?; + module.associated_function("is_whitespace", char::is_whitespace)?; + module.associated_function("to_digit", char::to_digit)?; Ok(module) } diff --git a/crates/rune/src/modules/collections/hash_map.rs b/crates/rune/src/modules/collections/hash_map.rs index c9407250a..0e2a5d67a 100644 --- a/crates/rune/src/modules/collections/hash_map.rs +++ b/crates/rune/src/modules/collections/hash_map.rs @@ -11,22 +11,22 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> { module.ty::()?; module.function_meta(HashMap::__new__meta)?; module.function_meta(hashmap_from)?; - module.inst_fn("clear", HashMap::clear)?; - module.inst_fn("clone", HashMap::clone)?; - module.inst_fn("contains_key", HashMap::contains_key)?; - module.inst_fn("extend", HashMap::extend)?; - module.inst_fn("get", HashMap::get)?; - module.inst_fn("insert", HashMap::insert)?; - module.inst_fn("is_empty", HashMap::is_empty)?; - module.inst_fn("iter", HashMap::iter)?; - module.inst_fn("keys", HashMap::keys)?; - module.inst_fn("len", HashMap::len)?; - module.inst_fn("remove", HashMap::remove)?; - module.inst_fn("values", HashMap::values)?; - module.inst_fn(Protocol::INTO_ITER, HashMap::iter)?; - module.inst_fn(Protocol::INDEX_SET, HashMap::index_set)?; - module.inst_fn(Protocol::INDEX_GET, HashMap::index_get)?; - module.inst_fn(Protocol::STRING_DEBUG, HashMap::string_debug)?; + module.associated_function("clear", HashMap::clear)?; + module.associated_function("clone", HashMap::clone)?; + module.associated_function("contains_key", HashMap::contains_key)?; + module.associated_function("extend", HashMap::extend)?; + module.associated_function("get", HashMap::get)?; + module.associated_function("insert", HashMap::insert)?; + module.associated_function("is_empty", HashMap::is_empty)?; + module.associated_function("iter", HashMap::iter)?; + module.associated_function("keys", HashMap::keys)?; + module.associated_function("len", HashMap::len)?; + module.associated_function("remove", HashMap::remove)?; + module.associated_function("values", HashMap::values)?; + module.associated_function(Protocol::INTO_ITER, HashMap::iter)?; + module.associated_function(Protocol::INDEX_SET, HashMap::index_set)?; + module.associated_function(Protocol::INDEX_GET, HashMap::index_get)?; + module.associated_function(Protocol::STRING_DEBUG, HashMap::string_debug)?; Ok(()) } diff --git a/crates/rune/src/modules/collections/hash_set.rs b/crates/rune/src/modules/collections/hash_set.rs index 9b28a0285..1c22fff8d 100644 --- a/crates/rune/src/modules/collections/hash_set.rs +++ b/crates/rune/src/modules/collections/hash_set.rs @@ -11,21 +11,21 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> { module.ty::()?; module.function(["HashSet", "new"], HashSet::new)?; module.function(["HashSet", "from"], hashset_from)?; - module.inst_fn("clear", HashSet::clear)?; - module.inst_fn("clone", HashSet::clone)?; - module.inst_fn("contains", HashSet::contains)?; - module.inst_fn("difference", HashSet::difference)?; - module.inst_fn("extend", HashSet::extend)?; - module.inst_fn("insert", HashSet::insert)?; - module.inst_fn("intersection", HashSet::intersection)?; - module.inst_fn("is_empty", HashSet::is_empty)?; - module.inst_fn("iter", HashSet::iter)?; - module.inst_fn("len", HashSet::len)?; - module.inst_fn("remove", HashSet::remove)?; - module.inst_fn("union", HashSet::union)?; - module.inst_fn(Protocol::INTO_ITER, HashSet::iter)?; - module.inst_fn(Protocol::STRING_DEBUG, HashSet::string_debug)?; - module.inst_fn(Protocol::EQ, HashSet::eq)?; + module.associated_function("clear", HashSet::clear)?; + module.associated_function("clone", HashSet::clone)?; + module.associated_function("contains", HashSet::contains)?; + module.associated_function("difference", HashSet::difference)?; + module.associated_function("extend", HashSet::extend)?; + module.associated_function("insert", HashSet::insert)?; + module.associated_function("intersection", HashSet::intersection)?; + module.associated_function("is_empty", HashSet::is_empty)?; + module.associated_function("iter", HashSet::iter)?; + module.associated_function("len", HashSet::len)?; + module.associated_function("remove", HashSet::remove)?; + module.associated_function("union", HashSet::union)?; + module.associated_function(Protocol::INTO_ITER, HashSet::iter)?; + module.associated_function(Protocol::STRING_DEBUG, HashSet::string_debug)?; + module.associated_function(Protocol::EQ, HashSet::eq)?; Ok(()) } diff --git a/crates/rune/src/modules/collections/vec_deque.rs b/crates/rune/src/modules/collections/vec_deque.rs index 5774f867a..0582834f4 100644 --- a/crates/rune/src/modules/collections/vec_deque.rs +++ b/crates/rune/src/modules/collections/vec_deque.rs @@ -12,22 +12,22 @@ pub(super) fn setup(module: &mut Module) -> Result<(), ContextError> { module.function(["VecDeque", "with_capacity"], VecDeque::with_capacity)?; module.function(["VecDeque", "from"], vecdeque_from)?; - module.inst_fn("extend", VecDeque::extend)?; - module.inst_fn("insert", VecDeque::insert)?; - module.inst_fn("iter", VecDeque::iter)?; - module.inst_fn("len", VecDeque::len)?; - module.inst_fn("pop_back", VecDeque::pop_back)?; - module.inst_fn("pop_front", VecDeque::pop_front)?; - module.inst_fn("push_back", VecDeque::push_back)?; - module.inst_fn("push_front", VecDeque::push_front)?; - module.inst_fn("remove", VecDeque::remove)?; - module.inst_fn("reserve", VecDeque::reserve)?; - module.inst_fn("rotate_left", VecDeque::rotate_left)?; - module.inst_fn("rotate_right", VecDeque::rotate_right)?; - module.inst_fn(Protocol::INDEX_GET, VecDeque::get)?; - module.inst_fn(Protocol::INDEX_SET, VecDeque::set)?; - module.inst_fn(Protocol::INTO_ITER, VecDeque::iter)?; - module.inst_fn(Protocol::STRING_DEBUG, VecDeque::string_debug)?; + module.associated_function("extend", VecDeque::extend)?; + module.associated_function("insert", VecDeque::insert)?; + module.associated_function("iter", VecDeque::iter)?; + module.associated_function("len", VecDeque::len)?; + module.associated_function("pop_back", VecDeque::pop_back)?; + module.associated_function("pop_front", VecDeque::pop_front)?; + module.associated_function("push_back", VecDeque::push_back)?; + module.associated_function("push_front", VecDeque::push_front)?; + module.associated_function("remove", VecDeque::remove)?; + module.associated_function("reserve", VecDeque::reserve)?; + module.associated_function("rotate_left", VecDeque::rotate_left)?; + module.associated_function("rotate_right", VecDeque::rotate_right)?; + module.associated_function(Protocol::INDEX_GET, VecDeque::get)?; + module.associated_function(Protocol::INDEX_SET, VecDeque::set)?; + module.associated_function(Protocol::INTO_ITER, VecDeque::iter)?; + module.associated_function(Protocol::STRING_DEBUG, VecDeque::string_debug)?; Ok(()) } diff --git a/crates/rune/src/modules/float.rs b/crates/rune/src/modules/float.rs index a7d3b7eb2..4e117bc14 100644 --- a/crates/rune/src/modules/float.rs +++ b/crates/rune/src/modules/float.rs @@ -22,16 +22,14 @@ pub fn module() -> Result { module.ty::()?; module.function(["parse"], parse)?; - module.inst_fn("max", f64::max)?; - module.inst_fn("min", f64::min)?; + module.associated_function("max", f64::max)?; + module.associated_function("min", f64::min)?; #[cfg(feature = "std")] - module.inst_fn("abs", f64::abs)?; + module.associated_function("abs", f64::abs)?; #[cfg(feature = "std")] - module.inst_fn("powf", f64::powf)?; + module.associated_function("powf", f64::powf)?; #[cfg(feature = "std")] - module.inst_fn("powi", f64::powi)?; - - module.inst_fn("to_integer", to_integer)?; - + module.associated_function("powi", f64::powi)?; + module.associated_function("to_integer", to_integer)?; Ok(module) } diff --git a/crates/rune/src/modules/fmt.rs b/crates/rune/src/modules/fmt.rs index 73a892ce4..2d644c041 100644 --- a/crates/rune/src/modules/fmt.rs +++ b/crates/rune/src/modules/fmt.rs @@ -15,7 +15,7 @@ use crate::{ContextError, Module}; pub fn module() -> Result { let mut module = Module::with_crate_item("std", ["fmt"]).with_unique("std::fmt"); module.ty::()?; - module.inst_fn(Protocol::STRING_DISPLAY, format_fmt_error)?; + module.associated_function(Protocol::STRING_DISPLAY, format_fmt_error)?; module.macro_meta(format)?; module.ty::()?; diff --git a/crates/rune/src/modules/generator.rs b/crates/rune/src/modules/generator.rs index 286603299..7b900a07d 100644 --- a/crates/rune/src/modules/generator.rs +++ b/crates/rune/src/modules/generator.rs @@ -7,12 +7,10 @@ use crate::{ContextError, Module}; pub fn module() -> Result { let mut module = Module::with_crate_item("std", ["generator"]); module.ty::>()?; - - module.inst_fn("next", Generator::::next)?; - module.inst_fn("resume", Generator::::resume)?; - module.inst_fn("iter", Generator::::into_iterator)?; - module.inst_fn(Protocol::INTO_ITER, Generator::::into_iterator)?; + module.associated_function("next", Generator::::next)?; + module.associated_function("resume", Generator::::resume)?; + module.associated_function("iter", Generator::::into_iterator)?; + module.associated_function(Protocol::INTO_ITER, Generator::::into_iterator)?; module.generator_state(["GeneratorState"])?; - Ok(module) } diff --git a/crates/rune/src/modules/int.rs b/crates/rune/src/modules/int.rs index b00994d0f..2e3b3fadc 100644 --- a/crates/rune/src/modules/int.rs +++ b/crates/rune/src/modules/int.rs @@ -11,30 +11,30 @@ pub fn module() -> Result { module.ty::()?; module.function(["parse"], parse)?; - module.inst_fn("to_float", to_float)?; - - module.inst_fn("max", i64::max)?; - module.inst_fn("min", i64::min)?; - module.inst_fn("abs", i64::abs)?; - module.inst_fn("pow", i64::pow)?; - - module.inst_fn("checked_add", i64::checked_add)?; - module.inst_fn("checked_sub", i64::checked_sub)?; - module.inst_fn("checked_div", i64::checked_div)?; - module.inst_fn("checked_mul", i64::checked_mul)?; - module.inst_fn("checked_rem", i64::checked_rem)?; - - module.inst_fn("wrapping_add", i64::wrapping_add)?; - module.inst_fn("wrapping_sub", i64::wrapping_sub)?; - module.inst_fn("wrapping_div", i64::wrapping_div)?; - module.inst_fn("wrapping_mul", i64::wrapping_mul)?; - module.inst_fn("wrapping_rem", i64::wrapping_rem)?; - - module.inst_fn("saturating_add", i64::saturating_add)?; - module.inst_fn("saturating_sub", i64::saturating_sub)?; - module.inst_fn("saturating_mul", i64::saturating_mul)?; - module.inst_fn("saturating_abs", i64::saturating_abs)?; - module.inst_fn("saturating_pow", i64::saturating_pow)?; + module.associated_function("to_float", to_float)?; + + module.associated_function("max", i64::max)?; + module.associated_function("min", i64::min)?; + module.associated_function("abs", i64::abs)?; + module.associated_function("pow", i64::pow)?; + + module.associated_function("checked_add", i64::checked_add)?; + module.associated_function("checked_sub", i64::checked_sub)?; + module.associated_function("checked_div", i64::checked_div)?; + module.associated_function("checked_mul", i64::checked_mul)?; + module.associated_function("checked_rem", i64::checked_rem)?; + + module.associated_function("wrapping_add", i64::wrapping_add)?; + module.associated_function("wrapping_sub", i64::wrapping_sub)?; + module.associated_function("wrapping_div", i64::wrapping_div)?; + module.associated_function("wrapping_mul", i64::wrapping_mul)?; + module.associated_function("wrapping_rem", i64::wrapping_rem)?; + + module.associated_function("saturating_add", i64::saturating_add)?; + module.associated_function("saturating_sub", i64::saturating_sub)?; + module.associated_function("saturating_mul", i64::saturating_mul)?; + module.associated_function("saturating_abs", i64::saturating_abs)?; + module.associated_function("saturating_pow", i64::saturating_pow)?; Ok(module) } diff --git a/crates/rune/src/modules/io.rs b/crates/rune/src/modules/io.rs index d88a0ad9d..aab4db8ba 100644 --- a/crates/rune/src/modules/io.rs +++ b/crates/rune/src/modules/io.rs @@ -33,7 +33,7 @@ pub fn module(stdio: bool) -> Result { ]); module.ty::()?; - module.inst_fn(Protocol::STRING_DISPLAY, format_io_error)?; + module.associated_function(Protocol::STRING_DISPLAY, format_io_error)?; if stdio { module.function_meta(print_impl)?; diff --git a/crates/rune/src/modules/iter.rs b/crates/rune/src/modules/iter.rs index b399b0040..849c40894 100644 --- a/crates/rune/src/modules/iter.rs +++ b/crates/rune/src/modules/iter.rs @@ -12,30 +12,30 @@ pub fn module() -> Result { module.ty::()?; // Sorted for ease of finding - module.inst_fn("chain", Iterator::chain)?; + module.associated_function("chain", Iterator::chain)?; module.function_meta(collect_object)?; module.function_meta(collect_vec)?; module.function_meta(collect_tuple)?; - module.inst_fn("enumerate", Iterator::enumerate)?; - module.inst_fn("filter", Iterator::filter)?; - module.inst_fn("find", Iterator::find)?; - module.inst_fn("flat_map", Iterator::flat_map)?; - module.inst_fn("map", Iterator::map)?; - module.inst_fn("next", Iterator::next)?; - module.inst_fn("next_back", Iterator::next_back)?; - module.inst_fn("peek", Iterator::peek)?; - module.inst_fn("peekable", Iterator::peekable)?; - module.inst_fn("product", Iterator::product)?; - module.inst_fn("fold", Iterator::fold)?; - module.inst_fn("rev", Iterator::rev)?; - module.inst_fn("size_hint", Iterator::size_hint)?; - module.inst_fn("sum", Iterator::sum)?; - module.inst_fn("skip", Iterator::skip)?; - module.inst_fn("take", Iterator::take)?; - module.inst_fn("count", Iterator::count)?; - module.inst_fn("all", Iterator::all)?; - module.inst_fn(Protocol::NEXT, Iterator::next)?; - module.inst_fn(Protocol::INTO_ITER, >::from)?; + module.associated_function("enumerate", Iterator::enumerate)?; + module.associated_function("filter", Iterator::filter)?; + module.associated_function("find", Iterator::find)?; + module.associated_function("flat_map", Iterator::flat_map)?; + module.associated_function("map", Iterator::map)?; + module.associated_function("next", Iterator::next)?; + module.associated_function("next_back", Iterator::next_back)?; + module.associated_function("peek", Iterator::peek)?; + module.associated_function("peekable", Iterator::peekable)?; + module.associated_function("product", Iterator::product)?; + module.associated_function("fold", Iterator::fold)?; + module.associated_function("rev", Iterator::rev)?; + module.associated_function("size_hint", Iterator::size_hint)?; + module.associated_function("sum", Iterator::sum)?; + module.associated_function("skip", Iterator::skip)?; + module.associated_function("take", Iterator::take)?; + module.associated_function("count", Iterator::count)?; + module.associated_function("all", Iterator::all)?; + module.associated_function(Protocol::NEXT, Iterator::next)?; + module.associated_function(Protocol::INTO_ITER, >::from)?; module.function_meta(range)?; module.function_meta(empty)?; diff --git a/crates/rune/src/modules/object.rs b/crates/rune/src/modules/object.rs index 7a98d50ec..a10a10015 100644 --- a/crates/rune/src/modules/object.rs +++ b/crates/rune/src/modules/object.rs @@ -15,16 +15,16 @@ pub fn module() -> Result { module.function_meta(Object::__with_capacity__meta)?; module.function_meta(Object::__len__meta)?; module.function_meta(Object::__is_empty__meta)?; - module.inst_fn("insert", Object::insert)?; - module.inst_fn("remove", remove)?; - module.inst_fn("clear", Object::clear)?; - module.inst_fn("contains_key", contains_key)?; - module.inst_fn("get", get)?; - - module.inst_fn("iter", Object::into_iterator)?; - module.inst_fn(Protocol::INTO_ITER, Object::into_iterator)?; - module.inst_fn("keys", keys)?; - module.inst_fn("values", values)?; + module.associated_function("insert", Object::insert)?; + module.associated_function("remove", remove)?; + module.associated_function("clear", Object::clear)?; + module.associated_function("contains_key", contains_key)?; + module.associated_function("get", get)?; + + module.associated_function("iter", Object::into_iterator)?; + module.associated_function(Protocol::INTO_ITER, Object::into_iterator)?; + module.associated_function("keys", keys)?; + module.associated_function("values", values)?; Ok(module) } diff --git a/crates/rune/src/modules/ops.rs b/crates/rune/src/modules/ops.rs index 527c069d8..82f79ab27 100644 --- a/crates/rune/src/modules/ops.rs +++ b/crates/rune/src/modules/ops.rs @@ -23,20 +23,22 @@ pub fn module() -> Result { "* `..=`", ]); - module.field_fn(Protocol::GET, "start", |r: &Range| r.start.clone())?; - module.field_fn(Protocol::SET, "start", range_set_start)?; + module.field_function(Protocol::GET, "start", |r: &Range| r.start.clone())?; + module.field_function(Protocol::SET, "start", range_set_start)?; - module.field_fn(Protocol::GET, "end", |r: &Range| r.end.clone())?; - module.field_fn(Protocol::SET, "end", range_set_end)?; - module.inst_fn(Protocol::INTO_ITER, Range::into_iterator)?; + module.field_function(Protocol::GET, "end", |r: &Range| r.end.clone())?; + module.field_function(Protocol::SET, "end", range_set_end)?; + module.associated_function(Protocol::INTO_ITER, Range::into_iterator)?; module.function_meta(Range::__contains_int__meta)?; - module.inst_fn("iter", Range::into_iterator)?.docs([ - "Iterate over the range.", - "", - "This panics if the range is not a well-defined range.", - ]); + module + .associated_function("iter", Range::into_iterator)? + .docs([ + "Iterate over the range.", + "", + "This panics if the range is not a well-defined range.", + ]); module.ty::()?.docs([ "The type of a function in Rune.", diff --git a/crates/rune/src/modules/option.rs b/crates/rune/src/modules/option.rs index 383b10861..e522f70d7 100644 --- a/crates/rune/src/modules/option.rs +++ b/crates/rune/src/modules/option.rs @@ -11,18 +11,18 @@ pub fn module() -> Result { let mut module = Module::with_crate_item("std", ["option"]); module.option(["Option"])?; // Sorted for ease of finding - module.inst_fn("and_then", and_then_impl)?; - module.inst_fn("expect", expect_impl)?; - module.inst_fn("is_none", Option::::is_none)?; - module.inst_fn("is_some", Option::::is_some)?; - module.inst_fn("iter", option_iter)?; - module.inst_fn("map", map_impl)?; - module.inst_fn("take", take_impl)?; - module.inst_fn("transpose", transpose_impl)?; - module.inst_fn("unwrap", unwrap_impl)?; - module.inst_fn("unwrap_or", Option::::unwrap_or)?; + module.associated_function("and_then", and_then_impl)?; + module.associated_function("expect", expect_impl)?; + module.associated_function("is_none", Option::::is_none)?; + module.associated_function("is_some", Option::::is_some)?; + module.associated_function("iter", option_iter)?; + module.associated_function("map", map_impl)?; + module.associated_function("take", take_impl)?; + module.associated_function("transpose", transpose_impl)?; + module.associated_function("unwrap", unwrap_impl)?; + module.associated_function("unwrap_or", Option::::unwrap_or)?; module.function_meta(unwrap_or_else)?; - module.inst_fn(Protocol::INTO_ITER, option_iter)?; + module.associated_function(Protocol::INTO_ITER, option_iter)?; Ok(module) } diff --git a/crates/rune/src/modules/result.rs b/crates/rune/src/modules/result.rs index 94c1caf1a..96f0dd100 100644 --- a/crates/rune/src/modules/result.rs +++ b/crates/rune/src/modules/result.rs @@ -21,13 +21,13 @@ pub fn module() -> Result { .static_docs(&["Contains the error value"]); module.function_meta(ok)?; - module.inst_fn("is_ok", is_ok)?; - module.inst_fn("is_err", is_err)?; - module.inst_fn("unwrap", unwrap_impl)?; - module.inst_fn("unwrap_or", Result::::unwrap_or)?; - module.inst_fn("expect", expect_impl)?; - module.inst_fn("and_then", and_then_impl)?; - module.inst_fn("map", map_impl)?; + module.associated_function("is_ok", is_ok)?; + module.associated_function("is_err", is_err)?; + module.associated_function("unwrap", unwrap_impl)?; + module.associated_function("unwrap_or", Result::::unwrap_or)?; + module.associated_function("expect", expect_impl)?; + module.associated_function("and_then", and_then_impl)?; + module.associated_function("map", map_impl)?; Ok(module) } diff --git a/crates/rune/src/modules/stream.rs b/crates/rune/src/modules/stream.rs index e8bb3bc49..3b89facac 100644 --- a/crates/rune/src/modules/stream.rs +++ b/crates/rune/src/modules/stream.rs @@ -7,7 +7,7 @@ use crate::{ContextError, Module}; pub fn module() -> Result { let mut module = Module::with_crate_item("std", ["stream"]); module.ty::>()?; - module.async_inst_fn("next", Stream::::next)?; - module.async_inst_fn("resume", Stream::::resume)?; + module.associated_function("next", Stream::::next)?; + module.associated_function("resume", Stream::::resume)?; Ok(module) } diff --git a/crates/rune/src/modules/string.rs b/crates/rune/src/modules/string.rs index 7a0bcff25..3d813ae6a 100644 --- a/crates/rune/src/modules/string.rs +++ b/crates/rune/src/modules/string.rs @@ -19,33 +19,33 @@ pub fn module() -> Result { module.function(["String", "new"], String::new)?; module.function(["String", "with_capacity"], String::with_capacity)?; - module.inst_fn("cmp", str::cmp)?; - module.inst_fn("len", String::len)?; - module.inst_fn("starts_with", str::starts_with::<&str>)?; - module.inst_fn("ends_with", str::ends_with::<&str>)?; - module.inst_fn("capacity", String::capacity)?; - module.inst_fn("clear", String::clear)?; - module.inst_fn("contains", str::contains::<&str>)?; - module.inst_fn("push", String::push)?; - module.inst_fn("push_str", String::push_str)?; - module.inst_fn("reserve", String::reserve)?; - module.inst_fn("reserve_exact", String::reserve_exact)?; - module.inst_fn("into_bytes", into_bytes)?; - module.inst_fn("clone", String::clone)?; - module.inst_fn("shrink_to_fit", String::shrink_to_fit)?; - module.inst_fn("char_at", char_at)?; - module.inst_fn("split", string_split)?; - module.inst_fn("trim", string_trim)?; - module.inst_fn("trim_end", string_trim_end)?; - module.inst_fn("replace", str::replace::<&str>)?; + module.associated_function("cmp", str::cmp)?; + module.associated_function("len", String::len)?; + module.associated_function("starts_with", str::starts_with::<&str>)?; + module.associated_function("ends_with", str::ends_with::<&str>)?; + module.associated_function("capacity", String::capacity)?; + module.associated_function("clear", String::clear)?; + module.associated_function("contains", str::contains::<&str>)?; + module.associated_function("push", String::push)?; + module.associated_function("push_str", String::push_str)?; + module.associated_function("reserve", String::reserve)?; + module.associated_function("reserve_exact", String::reserve_exact)?; + module.associated_function("into_bytes", into_bytes)?; + module.associated_function("clone", String::clone)?; + module.associated_function("shrink_to_fit", String::shrink_to_fit)?; + module.associated_function("char_at", char_at)?; + module.associated_function("split", string_split)?; + module.associated_function("trim", string_trim)?; + module.associated_function("trim_end", string_trim_end)?; + module.associated_function("replace", str::replace::<&str>)?; // TODO: deprecate this variant. - module.inst_fn("split_str", string_split)?; - module.inst_fn("is_empty", str::is_empty)?; - module.inst_fn("chars", string_chars)?; - module.inst_fn(Protocol::ADD, add)?; - module.inst_fn(Protocol::ADD_ASSIGN, String::push_str)?; - module.inst_fn(Protocol::INDEX_GET, string_index_get)?; - module.inst_fn("get", string_get)?; + module.associated_function("split_str", string_split)?; + module.associated_function("is_empty", str::is_empty)?; + module.associated_function("chars", string_chars)?; + module.associated_function(Protocol::ADD, add)?; + module.associated_function(Protocol::ADD_ASSIGN, String::push_str)?; + module.associated_function(Protocol::INDEX_GET, string_index_get)?; + module.associated_function("get", string_get)?; // TODO: parameterize once generics are available. module.function(["parse_int"], parse_int)?; @@ -64,7 +64,7 @@ impl NotCharBoundary { } fn install(m: &mut Module) -> Result<(), ContextError> { - m.inst_fn(Protocol::STRING_DISPLAY, Self::string_display)?; + m.associated_function(Protocol::STRING_DISPLAY, Self::string_display)?; Ok(()) } } diff --git a/crates/rune/src/modules/vec.rs b/crates/rune/src/modules/vec.rs index 373a5cad1..524c1ecab 100644 --- a/crates/rune/src/modules/vec.rs +++ b/crates/rune/src/modules/vec.rs @@ -13,19 +13,19 @@ pub fn module() -> Result { module.ty::()?; module.function(["Vec", "new"], Vec::new)?; - module.inst_fn("clear", Vec::clear)?; - module.inst_fn("clone", Vec::clone)?; - module.inst_fn("extend", Vec::extend)?; + module.associated_function("clear", Vec::clear)?; + module.associated_function("clone", Vec::clone)?; + module.associated_function("extend", Vec::extend)?; module.function_meta(get)?; - module.inst_fn("iter", Vec::into_iterator)?; - module.inst_fn("len", Vec::len)?; - module.inst_fn("pop", Vec::pop)?; - module.inst_fn("push", Vec::push)?; - module.inst_fn("remove", Vec::remove)?; + module.associated_function("iter", Vec::into_iterator)?; + module.associated_function("len", Vec::len)?; + module.associated_function("pop", Vec::pop)?; + module.associated_function("push", Vec::push)?; + module.associated_function("remove", Vec::remove)?; module.function_meta(sort_by)?; - module.inst_fn("insert", Vec::insert)?; - module.inst_fn(Protocol::INTO_ITER, Vec::into_iterator)?; - module.inst_fn(Protocol::INDEX_SET, Vec::set)?; + module.associated_function("insert", Vec::insert)?; + module.associated_function(Protocol::INTO_ITER, Vec::into_iterator)?; + module.associated_function(Protocol::INDEX_SET, Vec::set)?; module.function_meta(sort_int)?; Ok(module) diff --git a/crates/rune/src/runtime/function.rs b/crates/rune/src/runtime/function.rs index 8d3461531..dd0c445f7 100644 --- a/crates/rune/src/runtime/function.rs +++ b/crates/rune/src/runtime/function.rs @@ -48,21 +48,8 @@ impl Function { /// assert_eq!(value, 42); /// # Ok::<_, rune::Error>(()) /// ``` - pub fn function(f: Func) -> Self - where - Func: module::Function, - { - Self(FunctionImpl { - inner: Inner::FnHandler(FnHandler { - handler: Arc::new(move |stack, args| f.fn_call(stack, args)), - hash: Hash::EMPTY, - }), - }) - } - - /// Construct an `async` [Function] from a Rust closure. /// - /// # Examples + /// Asynchronous functions: /// /// ``` /// use rune::{Hash, Vm}; @@ -81,7 +68,7 @@ impl Function { /// let unit = rune::prepare(&mut sources).build()?; /// let mut vm = Vm::without_runtime(Arc::new(unit)); /// - /// let function = Function::async_function(|value: u32| async move { value + 1 }); + /// let function = Function::function(|value: u32| async move { value + 1 }); /// /// assert_eq!(function.type_hash(), Hash::EMPTY); /// @@ -90,9 +77,10 @@ impl Function { /// assert_eq!(value, 42); /// # Ok(()) } /// ``` - pub fn async_function(f: Func) -> Self + pub fn new(f: F) -> Self where - Func: module::AsyncFunction, + F: module::Function, + K: module::FunctionKind, { Self(FunctionImpl { inner: Inner::FnHandler(FnHandler { @@ -102,6 +90,25 @@ impl Function { }) } + /// See [`Function::new`]. + #[deprecated = "Use Function::new() instead"] + pub fn function(f: F) -> Self + where + F: module::Function, + K: module::FunctionKind, + { + Self::new(f) + } + + /// See [`Function::function`]. + #[deprecated = "Use Function::function() instead"] + pub fn async_function(f: F) -> Self + where + F: module::Function, + { + Self::new(f) + } + /// Perform an asynchronous call over the function which also implements /// [Send]. pub async fn async_send_call(&self, args: A) -> VmResult diff --git a/crates/rune/src/runtime/protocol_caller.rs b/crates/rune/src/runtime/protocol_caller.rs index 944181096..715f220ad 100644 --- a/crates/rune/src/runtime/protocol_caller.rs +++ b/crates/rune/src/runtime/protocol_caller.rs @@ -24,7 +24,7 @@ impl ProtocolCaller for EnvProtocolCaller { { return crate::runtime::env::with(|context, unit| { let count = args.count() + 1; - let hash = Hash::instance_function(vm_try!(target.type_hash()), protocol.hash); + let hash = Hash::associated_function(vm_try!(target.type_hash()), protocol.hash); if let Some(UnitFn::Offset { offset, diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index 849cf2e19..4d6bb53c2 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -567,7 +567,7 @@ impl Value { /// a name without the use of a [`Vm`] and one is not provided through the /// environment. pub fn into_type_name(self) -> VmResult { - let hash = Hash::instance_function(vm_try!(self.type_hash()), Protocol::INTO_TYPE_NAME); + let hash = Hash::associated_function(vm_try!(self.type_hash()), Protocol::INTO_TYPE_NAME); crate::runtime::env::with(|context, unit| { if let Some(name) = context.constant(hash) { diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 6c18fda38..ad82fde13 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -488,7 +488,7 @@ impl Vm { // Safety: We hold onto the guard for the duration of this call. let _guard = unsafe { vm_try!(args.unsafe_into_stack(&mut self.stack)) }; - let hash = Hash::instance_function(type_hash, hash.to_type_hash()); + let hash = Hash::associated_function(type_hash, hash.to_type_hash()); if let Some(UnitFn::Offset { offset, @@ -527,7 +527,7 @@ impl Vm { { let count = args.count(); let full_count = count + 1; - let hash = Hash::field_fn(protocol, vm_try!(target.type_hash()), name); + let hash = Hash::field_function(protocol, vm_try!(target.type_hash()), name); self.stack.push(target); vm_try!(args.into_stack(&mut self.stack)); @@ -557,7 +557,7 @@ impl Vm { { let count = args.count(); let full_count = count + 1; - let hash = Hash::index_fn(protocol, vm_try!(target.type_hash()), Hash::index(index)); + let hash = Hash::index_function(protocol, vm_try!(target.type_hash()), Hash::index(index)); self.stack.push(target); vm_try!(args.into_stack(&mut self.stack)); @@ -2025,7 +2025,7 @@ impl Vm { fn op_load_instance_fn(&mut self, hash: Hash) -> Result<(), VmError> { let instance = self.stack.pop()?; let ty = instance.type_hash()?; - let hash = Hash::instance_function(ty, hash); + let hash = Hash::associated_function(ty, hash); self.stack.push(Value::Type(Type::new(hash))); Ok(()) } @@ -2759,7 +2759,7 @@ impl Vm { let args = args + 1; let instance = vm_try!(self.stack.at_offset_from_top(args)); let type_hash = vm_try!(instance.type_hash()); - let hash = Hash::instance_function(type_hash, hash); + let hash = Hash::associated_function(type_hash, hash); if let Some(UnitFn::Offset { offset, diff --git a/crates/rune/src/tests/bug_326.rs b/crates/rune/src/tests/bug_326.rs index 5cb9d812c..d2cfed621 100644 --- a/crates/rune/src/tests/bug_326.rs +++ b/crates/rune/src/tests/bug_326.rs @@ -38,7 +38,7 @@ fn bug_326() -> Result<()> { fn trim_module() -> Result { let mut m = Module::with_item(["mymodule"]); - m.inst_fn("trim_indent", trim_indent)?; + m.associated_function("trim_indent", trim_indent)?; Ok(m) } diff --git a/crates/rune/src/tests/bug_344.rs b/crates/rune/src/tests/bug_344.rs index e74cd19ed..7e48acc61 100644 --- a/crates/rune/src/tests/bug_344.rs +++ b/crates/rune/src/tests/bug_344.rs @@ -44,12 +44,12 @@ fn bug_344_inst_fn() -> Result<()> { let mut module = Module::new(); module.ty::()?; - module.inst_fn("function", function)?; + module.associated_function("function", function)?; context.install(module)?; let runtime = context.runtime(); - let hash = Hash::instance_function(::type_hash(), "function"); + let hash = Hash::associated_function(::type_hash(), "function"); let function = runtime.function(hash).expect("expect function"); @@ -73,7 +73,7 @@ fn bug_344_async_function() -> Result<()> { let mut context = Context::new(); let mut module = Module::new(); - module.async_function(["function"], function)?; + module.function(["function"], function)?; context.install(module)?; let runtime = context.runtime(); @@ -107,12 +107,12 @@ fn bug_344_async_inst_fn() -> Result<()> { let mut module = Module::new(); module.ty::()?; - module.async_inst_fn("function", function)?; + module.associated_function("function", function)?; context.install(module)?; let runtime = context.runtime(); - let hash = Hash::instance_function(::type_hash(), "function"); + let hash = Hash::associated_function(::type_hash(), "function"); let function = runtime.function(hash).expect("expect function"); diff --git a/crates/rune/src/tests/external_ops.rs b/crates/rune/src/tests/external_ops.rs index 048575def..4d3b7d9ba 100644 --- a/crates/rune/src/tests/external_ops.rs +++ b/crates/rune/src/tests/external_ops.rs @@ -34,8 +34,8 @@ fn test_external_ops_struct() -> Result<()> { let mut module = Module::new(); module.ty::()?; - module.inst_fn(Protocol::$protocol, External::value)?; - module.field_fn(Protocol::$protocol, "field", External::field)?; + module.associated_function(Protocol::$protocol, External::value)?; + module.field_function(Protocol::$protocol, "field", External::field)?; let mut context = Context::with_default_modules()?; context.install(module)?; @@ -118,8 +118,8 @@ fn test_external_ops_tuple() -> Result<()> { let mut module = Module::new(); module.ty::()?; - module.inst_fn(Protocol::$protocol, External::value)?; - module.index_fn(Protocol::$protocol, 1, External::field)?; + module.associated_function(Protocol::$protocol, External::value)?; + module.index_function(Protocol::$protocol, 1, External::field)?; let mut context = Context::with_default_modules()?; context.install(module)?; diff --git a/crates/rune/src/tests/type_name_native.rs b/crates/rune/src/tests/type_name_native.rs index b1f07dc2d..b9917b3d0 100644 --- a/crates/rune/src/tests/type_name_native.rs +++ b/crates/rune/src/tests/type_name_native.rs @@ -19,8 +19,8 @@ fn make_native_module() -> Result { let mut module = Module::with_crate("native_crate"); module.ty::()?; module.function(["native_fn"], native_fn)?; - module.inst_fn("instance_fn", NativeStruct::instance_fn)?; - module.field_fn(Protocol::GET, "x", NativeStruct::get_x)?; + module.associated_function("instance_fn", NativeStruct::instance_fn)?; + module.field_function(Protocol::GET, "x", NativeStruct::get_x)?; Ok(module) } diff --git a/crates/rune/tests/generic_native.rs b/crates/rune/tests/generic_native.rs index 755f29e60..3aafab7f5 100644 --- a/crates/rune/tests/generic_native.rs +++ b/crates/rune/tests/generic_native.rs @@ -31,10 +31,10 @@ where fn make_native_module() -> Result { let mut module = Module::with_crate("native_crate"); module.ty::>()?; - module.inst_fn("get_value", Generic::::get_value)?; + module.associated_function("get_value", Generic::::get_value)?; module.ty::>()?; - module.inst_fn("get_value", Generic::::get_value)?; + module.associated_function("get_value", Generic::::get_value)?; Ok(module) } diff --git a/crates/rune/tests/ui.rs b/crates/rune/tests/ui.rs new file mode 100644 index 000000000..870c2f95e --- /dev/null +++ b/crates/rune/tests/ui.rs @@ -0,0 +1,5 @@ +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/crates/rune/tests/ui/install_with_compat.rs b/crates/rune/tests/ui/install_with_compat.rs new file mode 100644 index 000000000..f2dbd42a9 --- /dev/null +++ b/crates/rune/tests/ui/install_with_compat.rs @@ -0,0 +1,10 @@ +use rune::Any; + +// Generates a warning that the path should no longer be using a string literal. +#[derive(Any)] +#[rune(install_with = "foo::bar")] +struct Struct { +} + +fn main() { +} diff --git a/crates/rune/tests/ui/install_with_compat.stderr b/crates/rune/tests/ui/install_with_compat.stderr new file mode 100644 index 000000000..5edd198b8 --- /dev/null +++ b/crates/rune/tests/ui/install_with_compat.stderr @@ -0,0 +1,5 @@ +error: String literals are no longer supported here, use a path like `foo :: bar` + --> tests/ui/install_with_compat.rs:5:23 + | +5 | #[rune(install_with = "foo::bar")] + | ^^^^^^^^^^ diff --git a/examples/examples/custom_instance_fn.rs b/examples/examples/custom_instance_fn.rs index e7f7123f7..9d75f7378 100644 --- a/examples/examples/custom_instance_fn.rs +++ b/examples/examples/custom_instance_fn.rs @@ -44,6 +44,6 @@ async fn main() -> rune::Result<()> { fn module() -> Result { let mut m = Module::with_item(["mymodule"]); - m.inst_fn("divide_by_three", divide_by_three)?; + m.associated_function("divide_by_three", divide_by_three)?; Ok(m) } diff --git a/examples/examples/custom_mul.rs b/examples/examples/custom_mul.rs index 905fe4871..ba9898f80 100644 --- a/examples/examples/custom_mul.rs +++ b/examples/examples/custom_mul.rs @@ -52,6 +52,6 @@ fn main() -> rune::Result<()> { fn module() -> Result { let mut m = Module::with_item(["module"]); m.ty::()?; - m.inst_fn(Protocol::MUL, Foo::mul)?; + m.associated_function(Protocol::MUL, Foo::mul)?; Ok(m) } diff --git a/examples/examples/references.rs b/examples/examples/references.rs index c151cca4f..36e2b9caa 100644 --- a/examples/examples/references.rs +++ b/examples/examples/references.rs @@ -18,7 +18,7 @@ impl Foo { fn main() -> rune::Result<()> { let mut module = Module::new(); module.ty::()?; - module.inst_fn(Protocol::ADD_ASSIGN, Foo::add_assign)?; + module.associated_function(Protocol::ADD_ASSIGN, Foo::add_assign)?; let mut context = rune_modules::default_context()?; context.install(module)?;