Skip wrapping if function returns Dynamicc.
This commit is contained in:
parent
707ece7e80
commit
3c9250b0bf
@ -16,7 +16,6 @@ use quote::{quote, quote_spanned};
|
|||||||
use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
|
use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
|
||||||
|
|
||||||
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
||||||
use crate::rhai_module::flatten_type_groups;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Index {
|
pub enum Index {
|
||||||
@ -48,10 +47,10 @@ impl FnSpecialAccess {
|
|||||||
match self {
|
match self {
|
||||||
FnSpecialAccess::None => None,
|
FnSpecialAccess::None => None,
|
||||||
FnSpecialAccess::Property(Property::Get(ref g)) => {
|
FnSpecialAccess::Property(Property::Get(ref g)) => {
|
||||||
Some((format!("get${}", g.to_string()), g.to_string(), g.span()))
|
Some((format!("{}{}", FN_GET, g), g.to_string(), g.span()))
|
||||||
}
|
}
|
||||||
FnSpecialAccess::Property(Property::Set(ref s)) => {
|
FnSpecialAccess::Property(Property::Set(ref s)) => {
|
||||||
Some((format!("set${}", s.to_string()), s.to_string(), s.span()))
|
Some((format!("{}{}", FN_SET, s), s.to_string(), s.span()))
|
||||||
}
|
}
|
||||||
FnSpecialAccess::Index(Index::Get) => Some((
|
FnSpecialAccess::Index(Index::Get) => Some((
|
||||||
FN_IDX_GET.to_string(),
|
FN_IDX_GET.to_string(),
|
||||||
@ -67,6 +66,14 @@ impl FnSpecialAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn flatten_type_groups(ty: &syn::Type) -> &syn::Type {
|
||||||
|
match ty {
|
||||||
|
syn::Type::Group(syn::TypeGroup { ref elem, .. })
|
||||||
|
| syn::Type::Paren(syn::TypeParen { ref elem, .. }) => flatten_type_groups(elem.as_ref()),
|
||||||
|
_ => ty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct ExportedFnParams {
|
pub(crate) struct ExportedFnParams {
|
||||||
pub name: Option<Vec<String>>,
|
pub name: Option<Vec<String>>,
|
||||||
@ -76,6 +83,8 @@ pub(crate) struct ExportedFnParams {
|
|||||||
pub special: FnSpecialAccess,
|
pub special: FnSpecialAccess,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const FN_GET: &str = "get$";
|
||||||
|
pub const FN_SET: &str = "set$";
|
||||||
pub const FN_IDX_GET: &str = "index$get$";
|
pub const FN_IDX_GET: &str = "index$get$";
|
||||||
pub const FN_IDX_SET: &str = "index$set$";
|
pub const FN_IDX_SET: &str = "index$set$";
|
||||||
|
|
||||||
@ -130,36 +139,24 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
"use attribute 'index_set' instead",
|
"use attribute 'index_set' instead",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
("name", Some(s)) if s.value().starts_with("get$") => {
|
("name", Some(s)) if s.value().starts_with(FN_GET) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
item_span,
|
item_span,
|
||||||
format!(
|
format!(
|
||||||
"use attribute 'getter = \"{}\"' instead",
|
"use attribute 'getter = \"{}\"' instead",
|
||||||
&s.value()["get$".len()..]
|
&s.value()[FN_GET.len()..]
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
("name", Some(s)) if s.value().starts_with("set$") => {
|
("name", Some(s)) if s.value().starts_with(FN_SET) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
item_span,
|
item_span,
|
||||||
format!(
|
format!(
|
||||||
"use attribute 'setter = \"{}\"' instead",
|
"use attribute 'setter = \"{}\"' instead",
|
||||||
&s.value()["set$".len()..]
|
&s.value()[FN_SET.len()..]
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
("name", Some(s)) if s.value().contains('$') => {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
s.span(),
|
|
||||||
"Rhai function names may not contain dollar sign",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
("name", Some(s)) if s.value().contains('.') => {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
s.span(),
|
|
||||||
"Rhai function names may not contain dot",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
("name", Some(s)) => name.push(s.value()),
|
("name", Some(s)) => name.push(s.value()),
|
||||||
("set", Some(s)) => {
|
("set", Some(s)) => {
|
||||||
special = match special {
|
special = match special {
|
||||||
@ -225,6 +222,7 @@ pub(crate) struct ExportedFn {
|
|||||||
entire_span: proc_macro2::Span,
|
entire_span: proc_macro2::Span,
|
||||||
signature: syn::Signature,
|
signature: syn::Signature,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
|
return_dynamic: bool,
|
||||||
mut_receiver: bool,
|
mut_receiver: bool,
|
||||||
params: ExportedFnParams,
|
params: ExportedFnParams,
|
||||||
}
|
}
|
||||||
@ -235,6 +233,10 @@ impl Parse for ExportedFn {
|
|||||||
let entire_span = fn_all.span();
|
let entire_span = fn_all.span();
|
||||||
let str_type_path = syn::parse2::<syn::Path>(quote! { str }).unwrap();
|
let str_type_path = syn::parse2::<syn::Path>(quote! { str }).unwrap();
|
||||||
|
|
||||||
|
let dynamic_type_path1 = syn::parse2::<syn::Path>(quote! { Dynamic }).unwrap();
|
||||||
|
let dynamic_type_path2 = syn::parse2::<syn::Path>(quote! { rhai::Dynamic }).unwrap();
|
||||||
|
let mut return_dynamic = false;
|
||||||
|
|
||||||
// #[cfg] attributes are not allowed on functions due to what is generated for them
|
// #[cfg] attributes are not allowed on functions due to what is generated for them
|
||||||
crate::attrs::deny_cfg_attr(&fn_all.attrs)?;
|
crate::attrs::deny_cfg_attr(&fn_all.attrs)?;
|
||||||
|
|
||||||
@ -250,11 +252,11 @@ impl Parse for ExportedFn {
|
|||||||
}) => true,
|
}) => true,
|
||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
||||||
match flatten_type_groups(ty.as_ref()) {
|
match flatten_type_groups(ty.as_ref()) {
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: Some(_),
|
mutability: Some(_),
|
||||||
..
|
..
|
||||||
}) => true,
|
}) => true,
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
@ -285,18 +287,18 @@ impl Parse for ExportedFn {
|
|||||||
_ => panic!("internal error: receiver argument outside of first position!?"),
|
_ => panic!("internal error: receiver argument outside of first position!?"),
|
||||||
};
|
};
|
||||||
let is_ok = match flatten_type_groups(ty.as_ref()) {
|
let is_ok = match flatten_type_groups(ty.as_ref()) {
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: Some(_),
|
mutability: Some(_),
|
||||||
..
|
..
|
||||||
}) => false,
|
}) => false,
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
matches!(flatten_type_groups(elem.as_ref()), &syn::Type::Path(ref p) if p.path == str_type_path)
|
matches!(flatten_type_groups(elem.as_ref()), &syn::Type::Path(ref p) if p.path == str_type_path)
|
||||||
}
|
}
|
||||||
&syn::Type::Verbatim(_) => false,
|
syn::Type::Verbatim(_) => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
if !is_ok {
|
if !is_ok {
|
||||||
@ -308,21 +310,26 @@ impl Parse for ExportedFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No returning references or pointers.
|
// Check return type.
|
||||||
if let syn::ReturnType::Type(_, ref rtype) = fn_all.sig.output {
|
if let syn::ReturnType::Type(_, ref rtype) = fn_all.sig.output {
|
||||||
match rtype.as_ref() {
|
match flatten_type_groups(rtype.as_ref()) {
|
||||||
&syn::Type::Ptr(_) => {
|
syn::Type::Ptr(_) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
fn_all.sig.output.span(),
|
fn_all.sig.output.span(),
|
||||||
"cannot return a pointer to Rhai",
|
"Rhai functions cannot return pointers",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
&syn::Type::Reference(_) => {
|
syn::Type::Reference(_) => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
fn_all.sig.output.span(),
|
fn_all.sig.output.span(),
|
||||||
"cannot return a reference to Rhai",
|
"Rhai functions cannot return references",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
syn::Type::Path(p)
|
||||||
|
if p.path == dynamic_type_path1 || p.path == dynamic_type_path2 =>
|
||||||
|
{
|
||||||
|
return_dynamic = true
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,6 +337,7 @@ impl Parse for ExportedFn {
|
|||||||
entire_span,
|
entire_span,
|
||||||
signature: fn_all.sig,
|
signature: fn_all.sig,
|
||||||
is_public,
|
is_public,
|
||||||
|
return_dynamic,
|
||||||
mut_receiver,
|
mut_receiver,
|
||||||
params: ExportedFnParams::default(),
|
params: ExportedFnParams::default(),
|
||||||
})
|
})
|
||||||
@ -419,7 +427,7 @@ impl ExportedFn {
|
|||||||
|
|
||||||
pub(crate) fn return_type(&self) -> Option<&syn::Type> {
|
pub(crate) fn return_type(&self) -> Option<&syn::Type> {
|
||||||
if let syn::ReturnType::Type(_, ref rtype) = self.signature.output {
|
if let syn::ReturnType::Type(_, ref rtype) = self.signature.output {
|
||||||
Some(rtype)
|
Some(flatten_type_groups(rtype))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -437,7 +445,7 @@ impl ExportedFn {
|
|||||||
{
|
{
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.span(),
|
||||||
"return_raw functions must return Result<T>",
|
"return_raw functions must return Result<T, Box<EvalAltResult>>",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,7 +475,7 @@ impl ExportedFn {
|
|||||||
FnSpecialAccess::Property(Property::Set(_)) if self.return_type().is_some() => {
|
FnSpecialAccess::Property(Property::Set(_)) if self.return_type().is_some() => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.span(),
|
||||||
"property setter must return no value",
|
"property setter cannot return any value",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
// 4a. Index getters must take the subject and the accessed "index" as arguments.
|
// 4a. Index getters must take the subject and the accessed "index" as arguments.
|
||||||
@ -495,7 +503,7 @@ impl ExportedFn {
|
|||||||
FnSpecialAccess::Index(Index::Set) if self.return_type().is_some() => {
|
FnSpecialAccess::Index(Index::Set) if self.return_type().is_some() => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.span(),
|
||||||
"index setter must return no value",
|
"index setter cannot return a value",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -532,7 +540,7 @@ impl ExportedFn {
|
|||||||
dynamic_signature.ident =
|
dynamic_signature.ident =
|
||||||
syn::Ident::new("dynamic_result_fn", proc_macro2::Span::call_site());
|
syn::Ident::new("dynamic_result_fn", proc_macro2::Span::call_site());
|
||||||
dynamic_signature.output = syn::parse2::<syn::ReturnType>(quote! {
|
dynamic_signature.output = syn::parse2::<syn::ReturnType>(quote! {
|
||||||
-> Result<Dynamic, EvalBox>
|
-> Result<Dynamic, Box<EvalAltResult>>
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let arguments: Vec<syn::Ident> = dynamic_signature
|
let arguments: Vec<syn::Ident> = dynamic_signature
|
||||||
@ -555,18 +563,22 @@ impl ExportedFn {
|
|||||||
.return_type()
|
.return_type()
|
||||||
.map(|r| r.span())
|
.map(|r| r.span())
|
||||||
.unwrap_or_else(|| proc_macro2::Span::call_site());
|
.unwrap_or_else(|| proc_macro2::Span::call_site());
|
||||||
if !self.params.return_raw {
|
if self.params.return_raw {
|
||||||
quote_spanned! { return_span=>
|
quote_spanned! { return_span=>
|
||||||
type EvalBox = Box<EvalAltResult>;
|
|
||||||
pub #dynamic_signature {
|
pub #dynamic_signature {
|
||||||
Ok(Dynamic::from(super::#name(#(#arguments),*)))
|
super::#name(#(#arguments),*)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if self.return_dynamic {
|
||||||
|
quote_spanned! { return_span=>
|
||||||
|
pub #dynamic_signature {
|
||||||
|
Ok(super::#name(#(#arguments),*))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote_spanned! { return_span=>
|
quote_spanned! { return_span=>
|
||||||
type EvalBox = Box<EvalAltResult>;
|
|
||||||
pub #dynamic_signature {
|
pub #dynamic_signature {
|
||||||
super::#name(#(#arguments),*)
|
Ok(Dynamic::from(super::#name(#(#arguments),*)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -734,9 +746,15 @@ impl ExportedFn {
|
|||||||
.map(|r| r.span())
|
.map(|r| r.span())
|
||||||
.unwrap_or_else(|| proc_macro2::Span::call_site());
|
.unwrap_or_else(|| proc_macro2::Span::call_site());
|
||||||
let return_expr = if !self.params.return_raw {
|
let return_expr = if !self.params.return_raw {
|
||||||
|
if self.return_dynamic {
|
||||||
|
quote_spanned! { return_span=>
|
||||||
|
Ok(#sig_name(#(#unpack_exprs),*))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
quote_spanned! { return_span=>
|
quote_spanned! { return_span=>
|
||||||
Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*)))
|
Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
quote_spanned! { return_span=>
|
quote_spanned! { return_span=>
|
||||||
#sig_name(#(#unpack_exprs),*)
|
#sig_name(#(#unpack_exprs),*)
|
||||||
|
@ -3,6 +3,7 @@ use std::collections::HashMap;
|
|||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
|
|
||||||
use crate::attrs::ExportScope;
|
use crate::attrs::ExportScope;
|
||||||
|
use crate::function::flatten_type_groups;
|
||||||
use crate::function::{ExportedFn, FnSpecialAccess};
|
use crate::function::{ExportedFn, FnSpecialAccess};
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
|
|
||||||
@ -174,14 +175,6 @@ pub(crate) fn generate_body(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn flatten_type_groups(ty: &syn::Type) -> &syn::Type {
|
|
||||||
match ty {
|
|
||||||
syn::Type::Group(syn::TypeGroup { ref elem, .. })
|
|
||||||
| syn::Type::Paren(syn::TypeParen { ref elem, .. }) => flatten_type_groups(elem.as_ref()),
|
|
||||||
_ => ty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
|
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
|
||||||
fn make_key(name: impl ToString, itemfn: &ExportedFn) -> String {
|
fn make_key(name: impl ToString, itemfn: &ExportedFn) -> String {
|
||||||
itemfn
|
itemfn
|
||||||
|
@ -88,7 +88,10 @@ mod function_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let err = syn::parse2::<ExportedFn>(input_tokens).unwrap_err();
|
let err = syn::parse2::<ExportedFn>(input_tokens).unwrap_err();
|
||||||
assert_eq!(format!("{}", err), "cannot return a reference to Rhai");
|
assert_eq!(
|
||||||
|
format!("{}", err),
|
||||||
|
"Rhai functions cannot return references"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -98,7 +101,7 @@ mod function_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let err = syn::parse2::<ExportedFn>(input_tokens).unwrap_err();
|
let err = syn::parse2::<ExportedFn>(input_tokens).unwrap_err();
|
||||||
assert_eq!(format!("{}", err), "cannot return a pointer to Rhai");
|
assert_eq!(format!("{}", err), "Rhai functions cannot return pointers");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -295,8 +298,7 @@ mod generate_tests {
|
|||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
type EvalBox = Box<EvalAltResult>;
|
pub fn dynamic_result_fn() -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
pub fn dynamic_result_fn() -> Result<Dynamic, EvalBox> {
|
|
||||||
Ok(Dynamic::from(super::do_nothing()))
|
Ok(Dynamic::from(super::do_nothing()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,8 +342,7 @@ mod generate_tests {
|
|||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
type EvalBox = Box<EvalAltResult>;
|
pub fn dynamic_result_fn(x: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
pub fn dynamic_result_fn(x: usize) -> Result<Dynamic, EvalBox> {
|
|
||||||
Ok(Dynamic::from(super::do_something(x)))
|
Ok(Dynamic::from(super::do_something(x)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,6 +352,51 @@ mod generate_tests {
|
|||||||
assert_streams_eq(item_fn.generate(), expected_tokens);
|
assert_streams_eq(item_fn.generate(), expected_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn return_dynamic() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub fn return_dynamic() -> (((rhai::Dynamic))) {
|
||||||
|
().into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub mod rhai_fn_return_dynamic {
|
||||||
|
use super::*;
|
||||||
|
struct Token();
|
||||||
|
impl PluginFunction for Token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic]
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 0usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 0usize);
|
||||||
|
Ok(return_dynamic())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { false }
|
||||||
|
fn is_variadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn token_callable() -> CallableFunction {
|
||||||
|
Token().into()
|
||||||
|
}
|
||||||
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
|
Token().input_types()
|
||||||
|
}
|
||||||
|
pub fn dynamic_result_fn() -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
|
Ok(super::return_dynamic())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_fn = syn::parse2::<ExportedFn>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_fn.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_arg_usize_fn_impl() {
|
fn one_arg_usize_fn_impl() {
|
||||||
let input_tokens: TokenStream = quote! {
|
let input_tokens: TokenStream = quote! {
|
||||||
@ -417,8 +463,7 @@ mod generate_tests {
|
|||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
type EvalBox = Box<EvalAltResult>;
|
pub fn dynamic_result_fn(x: usize, y: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
pub fn dynamic_result_fn(x: usize, y: usize) -> Result<Dynamic, EvalBox> {
|
|
||||||
Ok(Dynamic::from(super::add_together(x, y)))
|
Ok(Dynamic::from(super::add_together(x, y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -464,8 +509,7 @@ mod generate_tests {
|
|||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
type EvalBox = Box<EvalAltResult>;
|
pub fn dynamic_result_fn(x: &mut usize, y: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
pub fn dynamic_result_fn(x: &mut usize, y: usize) -> Result<Dynamic, EvalBox> {
|
|
||||||
Ok(Dynamic::from(super::increment(x, y)))
|
Ok(Dynamic::from(super::increment(x, y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,8 +554,7 @@ mod generate_tests {
|
|||||||
pub fn token_input_types() -> Box<[TypeId]> {
|
pub fn token_input_types() -> Box<[TypeId]> {
|
||||||
Token().input_types()
|
Token().input_types()
|
||||||
}
|
}
|
||||||
type EvalBox = Box<EvalAltResult>;
|
pub fn dynamic_result_fn(message: &str) -> Result<Dynamic, Box<EvalAltResult> > {
|
||||||
pub fn dynamic_result_fn(message: &str) -> Result<Dynamic, EvalBox> {
|
|
||||||
Ok(Dynamic::from(super::special_print(message)))
|
Ok(Dynamic::from(super::special_print(message)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: cannot return a reference to Rhai
|
error: Rhai functions cannot return references
|
||||||
--> $DIR/return_mut_ref.rs:12:38
|
--> $DIR/return_mut_ref.rs:12:38
|
||||||
|
|
|
|
||||||
12 | pub fn test_fn(input: &mut Clonable) -> &mut bool {
|
12 | pub fn test_fn(input: &mut Clonable) -> &mut bool {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: cannot return a pointer to Rhai
|
error: Rhai functions cannot return pointers
|
||||||
--> $DIR/return_pointer.rs:12:33
|
--> $DIR/return_pointer.rs:12:33
|
||||||
|
|
|
|
||||||
12 | pub fn test_fn(input: Clonable) -> *const str {
|
12 | pub fn test_fn(input: Clonable) -> *const str {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: cannot return a reference to Rhai
|
error: Rhai functions cannot return pointers
|
||||||
--> $DIR/return_shared_ref.rs:12:33
|
--> $DIR/return_shared_ref.rs:12:33
|
||||||
|
|
|
|
||||||
12 | pub fn test_fn(input: Clonable) -> &'static str {
|
12 | pub fn test_fn(input: Clonable) -> &'static str {
|
||||||
|
Loading…
Reference in New Issue
Block a user