commit
0c62a620ec
@ -1,6 +1,8 @@
|
|||||||
Rhai Release Notes
|
Rhai Release Notes
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
This version introduces functions with `Dynamic` parameters acting as wildcards.
|
||||||
|
|
||||||
Version 0.19.13
|
Version 0.19.13
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ pub fn print_type(ty: &syn::Type) -> String {
|
|||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ExportedFnParams {
|
pub struct ExportedFnParams {
|
||||||
pub name: Vec<String>,
|
pub name: Vec<String>,
|
||||||
pub return_raw: bool,
|
pub return_raw: Option<proc_macro2::Span>,
|
||||||
pub pure: bool,
|
pub pure: Option<proc_macro2::Span>,
|
||||||
pub skip: bool,
|
pub skip: bool,
|
||||||
pub special: FnSpecialAccess,
|
pub special: FnSpecialAccess,
|
||||||
pub namespace: FnNamespaceAccess,
|
pub namespace: FnNamespaceAccess,
|
||||||
@ -137,8 +137,8 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
items: attrs,
|
items: attrs,
|
||||||
} = info;
|
} = info;
|
||||||
let mut name = Vec::new();
|
let mut name = Vec::new();
|
||||||
let mut return_raw = false;
|
let mut return_raw = None;
|
||||||
let mut pure = false;
|
let mut pure = None;
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
let mut namespace = FnNamespaceAccess::Unset;
|
let mut namespace = FnNamespaceAccess::Unset;
|
||||||
let mut special = FnSpecialAccess::None;
|
let mut special = FnSpecialAccess::None;
|
||||||
@ -194,18 +194,28 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
return Err(syn::Error::new(s.span(), "extraneous value"))
|
return Err(syn::Error::new(s.span(), "extraneous value"))
|
||||||
}
|
}
|
||||||
|
|
||||||
("pure", None) => pure = true,
|
("pure", None) => pure = Some(item_span),
|
||||||
("return_raw", None) => return_raw = true,
|
("return_raw", None) => return_raw = Some(item_span),
|
||||||
("skip", None) => skip = true,
|
("skip", None) => skip = true,
|
||||||
("global", None) => match namespace {
|
("global", None) => match namespace {
|
||||||
FnNamespaceAccess::Unset => namespace = FnNamespaceAccess::Global,
|
FnNamespaceAccess::Unset => namespace = FnNamespaceAccess::Global,
|
||||||
FnNamespaceAccess::Global => (),
|
FnNamespaceAccess::Global => (),
|
||||||
_ => return Err(syn::Error::new(key.span(), "conflicting namespace")),
|
FnNamespaceAccess::Internal => {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
key.span(),
|
||||||
|
"namespace is already set to 'internal'",
|
||||||
|
))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
("internal", None) => match namespace {
|
("internal", None) => match namespace {
|
||||||
FnNamespaceAccess::Unset => namespace = FnNamespaceAccess::Internal,
|
FnNamespaceAccess::Unset => namespace = FnNamespaceAccess::Internal,
|
||||||
FnNamespaceAccess::Internal => (),
|
FnNamespaceAccess::Internal => (),
|
||||||
_ => return Err(syn::Error::new(key.span(), "conflicting namespace")),
|
FnNamespaceAccess::Global => {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
key.span(),
|
||||||
|
"namespace is already set to 'global'",
|
||||||
|
))
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
("get", Some(s)) => {
|
("get", Some(s)) => {
|
||||||
@ -478,10 +488,10 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn exported_name<'n>(&'n self) -> Cow<'n, str> {
|
pub fn exported_name<'n>(&'n self) -> Cow<'n, str> {
|
||||||
self.params.name.last().map_or_else(
|
self.params
|
||||||
|| self.signature.ident.to_string().into(),
|
.name
|
||||||
|s| s.as_str().into(),
|
.last()
|
||||||
)
|
.map_or_else(|| self.signature.ident.to_string().into(), |s| s.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arg_list(&self) -> impl Iterator<Item = &syn::FnArg> {
|
pub fn arg_list(&self) -> impl Iterator<Item = &syn::FnArg> {
|
||||||
@ -503,23 +513,31 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_params(&mut self, mut params: ExportedFnParams) -> syn::Result<()> {
|
pub fn set_params(&mut self, mut params: ExportedFnParams) -> syn::Result<()> {
|
||||||
// Several issues are checked here to avoid issues with diagnostics caused by raising them
|
// Several issues are checked here to avoid issues with diagnostics caused by raising them later.
|
||||||
// later.
|
|
||||||
//
|
//
|
||||||
// 1. Do not allow non-returning raw functions.
|
// 1a. Do not allow non-returning raw functions.
|
||||||
//
|
//
|
||||||
if params.return_raw && self.return_type().is_none() {
|
if params.return_raw.is_some() && self.return_type().is_none() {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
params.return_raw.unwrap(),
|
||||||
"functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>",
|
"functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1b. Do not allow non-method pure functions.
|
||||||
|
//
|
||||||
|
if params.pure.is_some() && !self.mutable_receiver() {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
params.pure.unwrap(),
|
||||||
|
"'pure' is not necessary on functions without a &mut first parameter",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
match params.special {
|
match params.special {
|
||||||
// 2a. Property getters must take only the subject as an argument.
|
// 2a. Property getters must take only the subject as an argument.
|
||||||
FnSpecialAccess::Property(Property::Get(_)) if self.arg_count() != 1 => {
|
FnSpecialAccess::Property(Property::Get(_)) if self.arg_count() != 1 => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.inputs.span(),
|
||||||
"property getter requires exactly 1 parameter",
|
"property getter requires exactly 1 parameter",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -533,21 +551,21 @@ impl ExportedFn {
|
|||||||
// 3a. Property setters must take the subject and a new value as arguments.
|
// 3a. Property setters must take the subject and a new value as arguments.
|
||||||
FnSpecialAccess::Property(Property::Set(_)) if self.arg_count() != 2 => {
|
FnSpecialAccess::Property(Property::Set(_)) if self.arg_count() != 2 => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.inputs.span(),
|
||||||
"property setter requires exactly 2 parameters",
|
"property setter requires exactly 2 parameters",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
// 3b. Property setters must return nothing.
|
// 3b. Property setters must return nothing.
|
||||||
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.output.span(),
|
||||||
"property setter cannot return any 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.
|
||||||
FnSpecialAccess::Index(Index::Get) if self.arg_count() != 2 => {
|
FnSpecialAccess::Index(Index::Get) if self.arg_count() != 2 => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.inputs.span(),
|
||||||
"index getter requires exactly 2 parameters",
|
"index getter requires exactly 2 parameters",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -561,15 +579,15 @@ impl ExportedFn {
|
|||||||
// 5a. Index setters must take the subject, "index", and new value as arguments.
|
// 5a. Index setters must take the subject, "index", and new value as arguments.
|
||||||
FnSpecialAccess::Index(Index::Set) if self.arg_count() != 3 => {
|
FnSpecialAccess::Index(Index::Set) if self.arg_count() != 3 => {
|
||||||
return Err(syn::Error::new(
|
return Err(syn::Error::new(
|
||||||
self.signature.span(),
|
self.signature.inputs.span(),
|
||||||
"index setter requires exactly 3 parameters",
|
"index setter requires exactly 3 parameters",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
// 5b. Index setters must return nothing.
|
// 5b. Index setters must return nothing.
|
||||||
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.output.span(),
|
||||||
"index setter cannot return a value",
|
"index setter cannot return any value",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -635,7 +653,7 @@ 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.is_some() {
|
||||||
quote_spanned! { return_span =>
|
quote_spanned! { return_span =>
|
||||||
pub #dynamic_signature {
|
pub #dynamic_signature {
|
||||||
#name(#(#arguments),*)
|
#name(#(#arguments),*)
|
||||||
@ -659,7 +677,7 @@ impl ExportedFn {
|
|||||||
pub fn generate_callable(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_callable(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
let callable_fn_name: syn::Ident = syn::Ident::new(
|
let callable_fn_name: syn::Ident = syn::Ident::new(
|
||||||
format!("{}_callable", on_type_name.to_lowercase()).as_str(),
|
&format!("{}_callable", on_type_name.to_lowercase()),
|
||||||
self.name().span(),
|
self.name().span(),
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
@ -672,7 +690,7 @@ impl ExportedFn {
|
|||||||
pub fn generate_input_names(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_input_names(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
let input_names_fn_name: syn::Ident = syn::Ident::new(
|
let input_names_fn_name: syn::Ident = syn::Ident::new(
|
||||||
format!("{}_input_names", on_type_name.to_lowercase()).as_str(),
|
&format!("{}_input_names", on_type_name.to_lowercase()),
|
||||||
self.name().span(),
|
self.name().span(),
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
@ -685,7 +703,7 @@ impl ExportedFn {
|
|||||||
pub fn generate_input_types(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_input_types(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
let input_types_fn_name: syn::Ident = syn::Ident::new(
|
let input_types_fn_name: syn::Ident = syn::Ident::new(
|
||||||
format!("{}_input_types", on_type_name.to_lowercase()).as_str(),
|
&format!("{}_input_types", on_type_name.to_lowercase()),
|
||||||
self.name().span(),
|
self.name().span(),
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
@ -698,7 +716,7 @@ impl ExportedFn {
|
|||||||
pub fn generate_return_type(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_return_type(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
||||||
let return_type_fn_name: syn::Ident = syn::Ident::new(
|
let return_type_fn_name: syn::Ident = syn::Ident::new(
|
||||||
format!("{}_return_type", on_type_name.to_lowercase()).as_str(),
|
&format!("{}_return_type", on_type_name.to_lowercase()),
|
||||||
self.name().span(),
|
self.name().span(),
|
||||||
);
|
);
|
||||||
quote! {
|
quote! {
|
||||||
@ -750,7 +768,7 @@ impl ExportedFn {
|
|||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
if !self.params().pure {
|
if !self.params().pure.is_some() {
|
||||||
let arg_lit_str =
|
let arg_lit_str =
|
||||||
syn::LitStr::new(&pat.to_token_stream().to_string(), pat.span());
|
syn::LitStr::new(&pat.to_token_stream().to_string(), pat.span());
|
||||||
unpack_statements.push(
|
unpack_statements.push(
|
||||||
@ -871,7 +889,7 @@ 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());
|
||||||
let return_expr = if !self.params.return_raw {
|
let return_expr = if !self.params.return_raw.is_some() {
|
||||||
if self.return_dynamic {
|
if self.return_dynamic {
|
||||||
quote_spanned! { return_span =>
|
quote_spanned! { return_span =>
|
||||||
Ok(#sig_name(#(#unpack_exprs),*))
|
Ok(#sig_name(#(#unpack_exprs),*))
|
||||||
|
@ -217,7 +217,7 @@ impl Module {
|
|||||||
|
|
||||||
pub fn exported_name(&self) -> Cow<str> {
|
pub fn exported_name(&self) -> Cow<str> {
|
||||||
if !self.params.name.is_empty() {
|
if !self.params.name.is_empty() {
|
||||||
self.params.name.as_str().into()
|
(&self.params.name).into()
|
||||||
} else {
|
} else {
|
||||||
self.module_name().to_string().into()
|
self.module_name().to_string().into()
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>
|
error: functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>
|
||||||
--> $DIR/export_fn_raw_noreturn.rs:10:5
|
--> $DIR/export_fn_raw_noreturn.rs:9:13
|
||||||
|
|
|
|
||||||
10 | pub fn test_fn(input: &mut Point) {
|
9 | #[export_fn(return_raw)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0425]: cannot find function `test_fn` in this scope
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
--> $DIR/export_fn_raw_noreturn.rs:19:5
|
--> $DIR/export_fn_raw_noreturn.rs:19:5
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>
|
error: functions marked with 'return_raw' must return Result<Dynamic, Box<EvalAltResult>>
|
||||||
--> $DIR/export_mod_raw_noreturn.rs:12:5
|
--> $DIR/export_mod_raw_noreturn.rs:11:11
|
||||||
|
|
|
|
||||||
12 | pub fn test_fn(input: &mut Point) {
|
11 | #[rhai_fn(return_raw)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_raw_noreturn.rs:22:5
|
--> $DIR/export_mod_raw_noreturn.rs:22:5
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: property getter requires exactly 1 parameter
|
error: property getter requires exactly 1 parameter
|
||||||
--> $DIR/rhai_fn_getter_signature.rs:13:9
|
--> $DIR/rhai_fn_getter_signature.rs:13:20
|
||||||
|
|
|
|
||||||
13 | pub fn test_fn(input: Point, value: bool) -> bool {
|
13 | pub fn test_fn(input: Point, value: bool) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_getter_signature.rs:23:8
|
--> $DIR/rhai_fn_getter_signature.rs:23:8
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: conflicting namespace
|
error: namespace is already set to 'global'
|
||||||
--> $DIR/rhai_fn_global_multiple.rs:12:23
|
--> $DIR/rhai_fn_global_multiple.rs:12:23
|
||||||
|
|
|
|
||||||
12 | #[rhai_fn(global, internal)]
|
12 | #[rhai_fn(global, internal)]
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: index getter requires exactly 2 parameters
|
error: index getter requires exactly 2 parameters
|
||||||
--> $DIR/rhai_fn_index_getter_signature.rs:13:9
|
--> $DIR/rhai_fn_index_getter_signature.rs:13:20
|
||||||
|
|
|
|
||||||
13 | pub fn test_fn(input: Point) -> bool {
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_index_getter_signature.rs:23:8
|
--> $DIR/rhai_fn_index_getter_signature.rs:23:8
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: index setter requires exactly 3 parameters
|
error: index setter requires exactly 3 parameters
|
||||||
--> $DIR/rhai_fn_setter_index_signature.rs:13:9
|
--> $DIR/rhai_fn_setter_index_signature.rs:13:20
|
||||||
|
|
|
|
||||||
13 | pub fn test_fn(input: Point) -> bool {
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_setter_index_signature.rs:23:8
|
--> $DIR/rhai_fn_setter_index_signature.rs:23:8
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: property setter cannot return any value
|
error: property setter cannot return any value
|
||||||
--> $DIR/rhai_fn_setter_return.rs:13:9
|
--> $DIR/rhai_fn_setter_return.rs:13:51
|
||||||
|
|
|
|
||||||
13 | pub fn test_fn(input: &mut Point, value: f32) -> bool {
|
13 | pub fn test_fn(input: &mut Point, value: f32) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_setter_return.rs:24:8
|
--> $DIR/rhai_fn_setter_return.rs:24:8
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: property setter requires exactly 2 parameters
|
error: property setter requires exactly 2 parameters
|
||||||
--> $DIR/rhai_fn_setter_signature.rs:13:9
|
--> $DIR/rhai_fn_setter_signature.rs:13:20
|
||||||
|
|
|
|
||||||
13 | pub fn test_fn(input: Point) -> bool {
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_setter_signature.rs:23:8
|
--> $DIR/rhai_fn_setter_signature.rs:23:8
|
||||||
|
Loading…
Reference in New Issue
Block a user