From 525ffe6f5a8db5990d1c11be33bd09614ede8a41 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 22:26:05 -0500 Subject: [PATCH 1/6] Improve diagnostics for duplicated names --- codegen/src/rhai_module.rs | 12 ++++++- codegen/ui_tests/rhai_mod_name_collisions.rs | 31 ++++++++++++++++ .../ui_tests/rhai_mod_name_collisions.stderr | 17 +++++++++ codegen/ui_tests/rhai_mod_unknown_type.rs | 27 ++++++++++++++ codegen/ui_tests/rhai_mod_unknown_type.stderr | 23 ++++++++++++ .../ui_tests/rhai_mod_unknown_type_return.rs | 27 ++++++++++++++ .../rhai_mod_unknown_type_return.stderr | 5 +++ diag_test/Cargo.toml | 13 +++++++ diag_test/test_template.rs | 35 +++++++++++++++++++ 9 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 codegen/ui_tests/rhai_mod_name_collisions.rs create mode 100644 codegen/ui_tests/rhai_mod_name_collisions.stderr create mode 100644 codegen/ui_tests/rhai_mod_unknown_type.rs create mode 100644 codegen/ui_tests/rhai_mod_unknown_type.stderr create mode 100644 codegen/ui_tests/rhai_mod_unknown_type_return.rs create mode 100644 codegen/ui_tests/rhai_mod_unknown_type_return.stderr create mode 100644 diag_test/Cargo.toml create mode 100644 diag_test/test_template.rs diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index 74144081..95f17ffc 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -177,7 +177,17 @@ pub(crate) fn check_rename_collisions(fns: &Vec) -> Result<(), syn:: } } else { let ident = itemfn.name(); - names.insert(ident.to_string(), ident.span()); + if let Some(other_span) = names.insert(ident.to_string(), ident.span()) { + let mut err = syn::Error::new( + ident.span(), + format!("duplicate function '{}'", ident.to_string()), + ); + err.combine(syn::Error::new( + other_span, + format!("duplicated function '{}'", ident.to_string()), + )); + return Err(err); + } } } for (new_name, attr_span) in renames.drain() { diff --git a/codegen/ui_tests/rhai_mod_name_collisions.rs b/codegen/ui_tests/rhai_mod_name_collisions.rs new file mode 100644 index 00000000..c7709555 --- /dev/null +++ b/codegen/ui_tests/rhai_mod_name_collisions.rs @@ -0,0 +1,31 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + pub use super::Point; + pub fn test_fn(input: Point) -> bool { + input.x > input.y + } + + pub fn test_fn(input: Point) -> bool { + input.x < input.y + } +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_module::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/rhai_mod_name_collisions.stderr b/codegen/ui_tests/rhai_mod_name_collisions.stderr new file mode 100644 index 00000000..539bd3eb --- /dev/null +++ b/codegen/ui_tests/rhai_mod_name_collisions.stderr @@ -0,0 +1,17 @@ +error: duplicate function 'test_fn' + --> $DIR/rhai_mod_name_collisions.rs:16:12 + | +16 | pub fn test_fn(input: Point) -> bool { + | ^^^^^^^ + +error: duplicated function 'test_fn' + --> $DIR/rhai_mod_name_collisions.rs:12:12 + | +12 | pub fn test_fn(input: Point) -> bool { + | ^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_module` + --> $DIR/rhai_mod_name_collisions.rs:26:8 + | +26 | if test_module::test_fn(n) { + | ^^^^^^^^^^^ use of undeclared type or module `test_module` diff --git a/codegen/ui_tests/rhai_mod_unknown_type.rs b/codegen/ui_tests/rhai_mod_unknown_type.rs new file mode 100644 index 00000000..7c19ab18 --- /dev/null +++ b/codegen/ui_tests/rhai_mod_unknown_type.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + pub use super::Point; + pub fn test_fn(input: Pointer) -> bool { + input.x < input.y + } +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_module::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/rhai_mod_unknown_type.stderr b/codegen/ui_tests/rhai_mod_unknown_type.stderr new file mode 100644 index 00000000..392f90a9 --- /dev/null +++ b/codegen/ui_tests/rhai_mod_unknown_type.stderr @@ -0,0 +1,23 @@ +error[E0412]: cannot find type `Pointer` in this scope + --> $DIR/rhai_mod_unknown_type.rs:12:27 + | +4 | pub struct Point { + | ---------------- similarly named struct `Point` defined here +... +12 | pub fn test_fn(input: Pointer) -> bool { + | ^^^^^^^ + | +help: a struct with a similar name exists + | +12 | pub fn test_fn(input: Point) -> bool { + | ^^^^^ +help: consider importing one of these items + | +11 | use core::fmt::Pointer; + | +11 | use crate::mem::fmt::Pointer; + | +11 | use std::fmt::Pointer; + | +11 | use syn::export::fmt::Pointer; + | diff --git a/codegen/ui_tests/rhai_mod_unknown_type_return.rs b/codegen/ui_tests/rhai_mod_unknown_type_return.rs new file mode 100644 index 00000000..c2287eaa --- /dev/null +++ b/codegen/ui_tests/rhai_mod_unknown_type_return.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + pub use super::Point; + pub fn test_fn(input: Point) -> boool { + input.x < input.y + } +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_module::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/rhai_mod_unknown_type_return.stderr b/codegen/ui_tests/rhai_mod_unknown_type_return.stderr new file mode 100644 index 00000000..43f2896c --- /dev/null +++ b/codegen/ui_tests/rhai_mod_unknown_type_return.stderr @@ -0,0 +1,5 @@ +error[E0412]: cannot find type `boool` in this scope + --> $DIR/rhai_mod_unknown_type_return.rs:12:37 + | +12 | pub fn test_fn(input: Point) -> boool { + | ^^^^^ help: a builtin type with a similar name exists: `bool` diff --git a/diag_test/Cargo.toml b/diag_test/Cargo.toml new file mode 100644 index 00000000..17998ecf --- /dev/null +++ b/diag_test/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "diag_test" +version = "0.1.0" +authors = ["J Henry Waugh "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "test_template" +path = "test_template.rs" + +[dependencies] +rhai = { version = "*", path = ".." } diff --git a/diag_test/test_template.rs b/diag_test/test_template.rs new file mode 100644 index 00000000..98088637 --- /dev/null +++ b/diag_test/test_template.rs @@ -0,0 +1,35 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + #[rhai_mod(name = "bar")] + pub mod test_mod { + #[rhai_fn(name = "foo")] + pub fn test_fn(input: Point) -> bool { + input.x > input.y + } + + #[rhai_fn(return_raw)] + pub fn test_fn_raw(input: Point) -> Result> { + Ok(Dynamic::from(input.x > input.y)) + } + } +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_module::test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} From 8de095fa361e61b8087128b1e89f971b3a1eb986 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 22:49:56 -0500 Subject: [PATCH 2/6] Improve diagnostics for non-clonable return types --- codegen/src/function.rs | 12 +++++--- .../ui_tests/rhai_fn_non_clonable_return.rs | 27 +++++++++++++++++ .../rhai_fn_non_clonable_return.stderr | 10 +++++++ .../ui_tests/rhai_mod_non_clonable_return.rs | 29 +++++++++++++++++++ 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 codegen/ui_tests/rhai_fn_non_clonable_return.rs create mode 100644 codegen/ui_tests/rhai_fn_non_clonable_return.stderr create mode 100644 codegen/ui_tests/rhai_mod_non_clonable_return.rs diff --git a/codegen/src/function.rs b/codegen/src/function.rs index b02a657d..a8862d20 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -314,15 +314,17 @@ impl ExportedFn { }) .collect(); + let return_span = self.return_type().map(|r| r.span()) + .unwrap_or_else(|| proc_macro2::Span::call_site()); if !self.params.return_raw { - quote! { + quote_spanned! { return_span=> type EvalBox = Box; pub #dynamic_signature { Ok(Dynamic::from(super::#name(#(#arguments),*))) } } } else { - quote_spanned! { self.return_type().unwrap().span()=> + quote_spanned! { return_span=> type EvalBox = Box; pub #dynamic_signature { super::#name(#(#arguments),*) @@ -484,12 +486,14 @@ impl ExportedFn { // Handle "raw returns", aka cases where the result is a dynamic or an error. // // This allows skipping the Dynamic::from wrap. + let return_span = self.return_type().map(|r| r.span()) + .unwrap_or_else(|| proc_macro2::Span::call_site()); let return_expr = if !self.params.return_raw { - quote! { + quote_spanned! { return_span=> Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*))) } } else { - quote_spanned! { self.return_type().unwrap().span()=> + quote_spanned! { return_span=> #sig_name(#(#unpack_exprs),*) } }; diff --git a/codegen/ui_tests/rhai_fn_non_clonable_return.rs b/codegen/ui_tests/rhai_fn_non_clonable_return.rs new file mode 100644 index 00000000..e2e2d788 --- /dev/null +++ b/codegen/ui_tests/rhai_fn_non_clonable_return.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +struct NonClonable { + a: f32, + b: u32, + c: char, + d: bool, +} + +#[export_fn] +pub fn test_fn(input: f32) -> NonClonable { + NonClonable { + a: input, + b: 10, + c: 'a', + d: true, + } +} + +fn main() { + let n = test_fn(20.0); + if n.c == 'a' { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/rhai_fn_non_clonable_return.stderr b/codegen/ui_tests/rhai_fn_non_clonable_return.stderr new file mode 100644 index 00000000..6184fd24 --- /dev/null +++ b/codegen/ui_tests/rhai_fn_non_clonable_return.stderr @@ -0,0 +1,10 @@ +error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied + --> $DIR/rhai_fn_non_clonable_return.rs:11:8 + | +11 | pub fn test_fn(input: f32) -> NonClonable { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable` + | + ::: /home/cryptkeeper/Desktop/Software/ytdl-replacement/rhai/src/any.rs:537:30 + | +537 | pub fn from(value: T) -> Self { + | ----- required by this bound in `rhai::Dynamic::from` diff --git a/codegen/ui_tests/rhai_mod_non_clonable_return.rs b/codegen/ui_tests/rhai_mod_non_clonable_return.rs new file mode 100644 index 00000000..fe8f5fff --- /dev/null +++ b/codegen/ui_tests/rhai_mod_non_clonable_return.rs @@ -0,0 +1,29 @@ +use rhai::plugin::*; + +struct NonClonable { + a: f32, + b: u32, + c: char, + d: bool, +} + +#[export_module] +pub mod test_mod { + pub fn test_fn(input: f32) -> NonClonable { + NonClonable { + a: input, + b: 10, + c: 'a', + d: true, + } + } +} + +fn main() { + let n = test_mod::test_fn(20.0); + if n.c == 'a' { + println!("yes"); + } else { + println!("no"); + } +} From fedc4c53385b054968275b9bb18bac2ab395b645 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 22:59:25 -0500 Subject: [PATCH 3/6] Add exported_fn tests for rhai_fn in module --- codegen/ui_tests/export_mod_bad_attr.rs | 27 ++++++++++++++++++ codegen/ui_tests/export_mod_bad_attr.stderr | 11 ++++++++ codegen/ui_tests/export_mod_bad_value.rs | 27 ++++++++++++++++++ codegen/ui_tests/export_mod_bad_value.stderr | 11 ++++++++ codegen/ui_tests/export_mod_cfg.rs | 28 +++++++++++++++++++ codegen/ui_tests/export_mod_cfg.stderr | 11 ++++++++ codegen/ui_tests/export_mod_extra_value.rs | 27 ++++++++++++++++++ .../ui_tests/export_mod_extra_value.stderr | 11 ++++++++ codegen/ui_tests/export_mod_junk_arg.rs | 27 ++++++++++++++++++ codegen/ui_tests/export_mod_junk_arg.stderr | 11 ++++++++ codegen/ui_tests/export_mod_missing_value.rs | 27 ++++++++++++++++++ .../ui_tests/export_mod_missing_value.stderr | 11 ++++++++ codegen/ui_tests/export_mod_path_attr.rs | 27 ++++++++++++++++++ codegen/ui_tests/export_mod_path_attr.stderr | 11 ++++++++ .../rhai_mod_non_clonable_return.stderr | 10 +++++++ 15 files changed, 277 insertions(+) create mode 100644 codegen/ui_tests/export_mod_bad_attr.rs create mode 100644 codegen/ui_tests/export_mod_bad_attr.stderr create mode 100644 codegen/ui_tests/export_mod_bad_value.rs create mode 100644 codegen/ui_tests/export_mod_bad_value.stderr create mode 100644 codegen/ui_tests/export_mod_cfg.rs create mode 100644 codegen/ui_tests/export_mod_cfg.stderr create mode 100644 codegen/ui_tests/export_mod_extra_value.rs create mode 100644 codegen/ui_tests/export_mod_extra_value.stderr create mode 100644 codegen/ui_tests/export_mod_junk_arg.rs create mode 100644 codegen/ui_tests/export_mod_junk_arg.stderr create mode 100644 codegen/ui_tests/export_mod_missing_value.rs create mode 100644 codegen/ui_tests/export_mod_missing_value.stderr create mode 100644 codegen/ui_tests/export_mod_path_attr.rs create mode 100644 codegen/ui_tests/export_mod_path_attr.stderr create mode 100644 codegen/ui_tests/rhai_mod_non_clonable_return.stderr diff --git a/codegen/ui_tests/export_mod_bad_attr.rs b/codegen/ui_tests/export_mod_bad_attr.rs new file mode 100644 index 00000000..8f8f7c2b --- /dev/null +++ b/codegen/ui_tests/export_mod_bad_attr.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(unknown = "thing")] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_bad_attr.stderr b/codegen/ui_tests/export_mod_bad_attr.stderr new file mode 100644 index 00000000..9704d74d --- /dev/null +++ b/codegen/ui_tests/export_mod_bad_attr.stderr @@ -0,0 +1,11 @@ +error: unknown attribute 'unknown' + --> $DIR/export_mod_bad_attr.rs:11:11 + | +11 | #[rhai_fn(unknown = "thing")] + | ^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_bad_attr.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_bad_value.rs b/codegen/ui_tests/export_mod_bad_value.rs new file mode 100644 index 00000000..c513dd35 --- /dev/null +++ b/codegen/ui_tests/export_mod_bad_value.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(name = true)] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_bad_value.stderr b/codegen/ui_tests/export_mod_bad_value.stderr new file mode 100644 index 00000000..63b22e4e --- /dev/null +++ b/codegen/ui_tests/export_mod_bad_value.stderr @@ -0,0 +1,11 @@ +error: expecting string literal + --> $DIR/export_mod_bad_value.rs:11:18 + | +11 | #[rhai_fn(name = true)] + | ^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_bad_value.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_cfg.rs b/codegen/ui_tests/export_mod_cfg.rs new file mode 100644 index 00000000..49838a73 --- /dev/null +++ b/codegen/ui_tests/export_mod_cfg.rs @@ -0,0 +1,28 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[cfg(not(feature = "foo"))] +#[rhai_fn] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_cfg.stderr b/codegen/ui_tests/export_mod_cfg.stderr new file mode 100644 index 00000000..b932ec86 --- /dev/null +++ b/codegen/ui_tests/export_mod_cfg.stderr @@ -0,0 +1,11 @@ +error: cfg attributes not allowed on this item + --> $DIR/export_mod_cfg.rs:11:1 + | +11 | #[cfg(not(feature = "foo"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_cfg.rs:23:8 + | +23 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_extra_value.rs b/codegen/ui_tests/export_mod_extra_value.rs new file mode 100644 index 00000000..6636f108 --- /dev/null +++ b/codegen/ui_tests/export_mod_extra_value.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(return_raw = "yes")] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_extra_value.stderr b/codegen/ui_tests/export_mod_extra_value.stderr new file mode 100644 index 00000000..0e3c65d6 --- /dev/null +++ b/codegen/ui_tests/export_mod_extra_value.stderr @@ -0,0 +1,11 @@ +error: extraneous value + --> $DIR/export_mod_extra_value.rs:11:24 + | +11 | #[rhai_fn(return_raw = "yes")] + | ^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_extra_value.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_junk_arg.rs b/codegen/ui_tests/export_mod_junk_arg.rs new file mode 100644 index 00000000..12190cf2 --- /dev/null +++ b/codegen/ui_tests/export_mod_junk_arg.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn("wheeeee")] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_junk_arg.stderr b/codegen/ui_tests/export_mod_junk_arg.stderr new file mode 100644 index 00000000..f4505bae --- /dev/null +++ b/codegen/ui_tests/export_mod_junk_arg.stderr @@ -0,0 +1,11 @@ +error: expecting identifier + --> $DIR/export_mod_junk_arg.rs:11:11 + | +11 | #[rhai_fn("wheeeee")] + | ^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_junk_arg.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_missing_value.rs b/codegen/ui_tests/export_mod_missing_value.rs new file mode 100644 index 00000000..f57c247b --- /dev/null +++ b/codegen/ui_tests/export_mod_missing_value.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(name)] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_missing_value.stderr b/codegen/ui_tests/export_mod_missing_value.stderr new file mode 100644 index 00000000..f479f5fa --- /dev/null +++ b/codegen/ui_tests/export_mod_missing_value.stderr @@ -0,0 +1,11 @@ +error: requires value + --> $DIR/export_mod_missing_value.rs:11:11 + | +11 | #[rhai_fn(name)] + | ^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_missing_value.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_path_attr.rs b/codegen/ui_tests/export_mod_path_attr.rs new file mode 100644 index 00000000..a489f042 --- /dev/null +++ b/codegen/ui_tests/export_mod_path_attr.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(rhai::name = "thing")] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_path_attr.stderr b/codegen/ui_tests/export_mod_path_attr.stderr new file mode 100644 index 00000000..d96d7c8c --- /dev/null +++ b/codegen/ui_tests/export_mod_path_attr.stderr @@ -0,0 +1,11 @@ +error: expecting attribute name + --> $DIR/export_mod_path_attr.rs:11:11 + | +11 | #[rhai_fn(rhai::name = "thing")] + | ^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_path_attr.rs:22:8 + | +22 | if test_mod::test_fn(n) { + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/rhai_mod_non_clonable_return.stderr b/codegen/ui_tests/rhai_mod_non_clonable_return.stderr new file mode 100644 index 00000000..db880026 --- /dev/null +++ b/codegen/ui_tests/rhai_mod_non_clonable_return.stderr @@ -0,0 +1,10 @@ +error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied + --> $DIR/rhai_mod_non_clonable_return.rs:12:12 + | +12 | pub fn test_fn(input: f32) -> NonClonable { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable` + | + ::: /home/cryptkeeper/Desktop/Software/ytdl-replacement/rhai/src/any.rs:537:30 + | +537 | pub fn from(value: T) -> Self { + | ----- required by this bound in `rhai::Dynamic::from` From 62dc142c5861e7bf8d13541ce72394efa5ba6b7e Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 23:08:34 -0500 Subject: [PATCH 4/6] Avoid bypassing setter checks by making fn.params.skip private --- codegen/src/function.rs | 10 +++++++++- codegen/src/module.rs | 14 +++++++------- codegen/src/rhai_module.rs | 8 ++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/codegen/src/function.rs b/codegen/src/function.rs index a8862d20..337eccab 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -111,7 +111,7 @@ pub(crate) struct ExportedFn { signature: syn::Signature, is_public: bool, mut_receiver: bool, - pub params: ExportedFnParams, + params: ExportedFnParams, } impl Parse for ExportedFn { @@ -218,6 +218,14 @@ impl Parse for ExportedFn { } impl ExportedFn { + pub(crate) fn params(&self) -> &ExportedFnParams { + &self.params + } + + pub(crate) fn skipped(&self) -> bool { + self.params.skip + } + pub(crate) fn mutable_receiver(&self) -> bool { self.mut_receiver } diff --git a/codegen/src/module.rs b/codegen/src/module.rs index 535ea9d7..b1a76f29 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -112,9 +112,9 @@ impl Parse for Module { true }; syn::parse2::(itemfn.to_token_stream()) - .map(|mut f| { - f.params = params; - f + .and_then(|mut f| { + f.set_params(params)?; + Ok(f) }) .map(|f| vec.push(f)) .map(|_| vec) @@ -411,7 +411,7 @@ mod module_tests { assert!(item_mod.consts.is_empty()); assert_eq!(item_mod.submodules.len(), 1); assert_eq!(item_mod.submodules[0].fns.len(), 1); - assert!(item_mod.submodules[0].fns[0].params.skip); + assert!(item_mod.submodules[0].fns[0].skipped()); assert!(item_mod.submodules[0].consts.is_empty()); assert!(item_mod.submodules[0].submodules.is_empty()); } @@ -433,7 +433,7 @@ mod module_tests { assert!(item_mod.fns.is_empty()); assert!(item_mod.consts.is_empty()); assert_eq!(item_mod.submodules.len(), 1); - assert!(item_mod.submodules[0].params.skip); + assert!(item_mod.submodules[0].skipped()); } #[test] @@ -466,7 +466,7 @@ mod module_tests { let item_mod = syn::parse2::(input_tokens).unwrap(); assert_eq!(item_mod.fns.len(), 1); - assert!(item_mod.fns[0].params.skip); + assert!(item_mod.fns[0].skipped()); assert!(item_mod.consts.is_empty()); } @@ -483,7 +483,7 @@ mod module_tests { let item_mod = syn::parse2::(input_tokens).unwrap(); assert_eq!(item_mod.fns.len(), 1); - assert!(item_mod.fns[0].params.skip); + assert!(item_mod.fns[0].skipped()); assert!(item_mod.consts.is_empty()); } diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index 95f17ffc..7e1aa106 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -56,7 +56,7 @@ pub(crate) fn generate_body( // NB: these are token streams, because reparsing messes up "> >" vs ">>" let mut gen_fn_tokens: Vec = Vec::new(); for function in fns { - if function.params.skip { + if function.skipped() { continue; } let fn_token_name = syn::Ident::new( @@ -64,7 +64,7 @@ pub(crate) fn generate_body( function.name().span(), ); let reg_name = function - .params + .params() .name .clone() .unwrap_or_else(|| function.name().to_string()); @@ -151,8 +151,8 @@ pub(crate) fn check_rename_collisions(fns: &Vec) -> Result<(), syn:: let mut renames = HashMap::::new(); let mut names = HashMap::::new(); for itemfn in fns.iter() { - if let Some(ref name) = itemfn.params.name { - let current_span = itemfn.params.span.as_ref().unwrap(); + if let Some(ref name) = itemfn.params().name { + let current_span = itemfn.params().span.as_ref().unwrap(); let key = itemfn.arg_list().fold(name.clone(), |mut argstr, fnarg| { let type_string: String = match fnarg { syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"), From d8e85df9dcea9b3f1f277e1823589a044d9306b8 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 23:11:22 -0500 Subject: [PATCH 5/6] Add return_raw tests for rhai_fn in module --- codegen/ui_tests/export_mod_raw_noreturn.rs | 28 +++++++++++++++++++ .../ui_tests/export_mod_raw_noreturn.stderr | 11 ++++++++ codegen/ui_tests/export_mod_raw_return.rs | 27 ++++++++++++++++++ codegen/ui_tests/export_mod_raw_return.stderr | 11 ++++++++ 4 files changed, 77 insertions(+) create mode 100644 codegen/ui_tests/export_mod_raw_noreturn.rs create mode 100644 codegen/ui_tests/export_mod_raw_noreturn.stderr create mode 100644 codegen/ui_tests/export_mod_raw_return.rs create mode 100644 codegen/ui_tests/export_mod_raw_return.stderr diff --git a/codegen/ui_tests/export_mod_raw_noreturn.rs b/codegen/ui_tests/export_mod_raw_noreturn.rs new file mode 100644 index 00000000..926f6286 --- /dev/null +++ b/codegen/ui_tests/export_mod_raw_noreturn.rs @@ -0,0 +1,28 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(return_raw)] +pub fn test_fn(input: &mut Point) { + input.x += 1.0; +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + test_mod::test_fn(&mut n); + if n.x >= 10.0 { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_raw_noreturn.stderr b/codegen/ui_tests/export_mod_raw_noreturn.stderr new file mode 100644 index 00000000..a548f339 --- /dev/null +++ b/codegen/ui_tests/export_mod_raw_noreturn.stderr @@ -0,0 +1,11 @@ +error: return_raw functions must return Result + --> $DIR/export_mod_raw_noreturn.rs:12:5 + | +12 | pub fn test_fn(input: &mut Point) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_mod` + --> $DIR/export_mod_raw_noreturn.rs:22:5 + | +22 | test_mod::test_fn(&mut n); + | ^^^^^^^^ use of undeclared type or module `test_mod` diff --git a/codegen/ui_tests/export_mod_raw_return.rs b/codegen/ui_tests/export_mod_raw_return.rs new file mode 100644 index 00000000..ae52301e --- /dev/null +++ b/codegen/ui_tests/export_mod_raw_return.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_mod { +#[rhai_fn(return_raw)] +pub fn test_fn(input: Point) -> bool { + input.x > input.y +} +} + +fn main() { + let n = Point { + x: 0.0, + y: 10.0, + }; + if test_mod::test_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_mod_raw_return.stderr b/codegen/ui_tests/export_mod_raw_return.stderr new file mode 100644 index 00000000..7d22f7a2 --- /dev/null +++ b/codegen/ui_tests/export_mod_raw_return.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/export_mod_raw_return.rs:12:8 + | +9 | #[export_module] + | ---------------- expected `std::result::Result>` because of return type +... +12 | pub fn test_fn(input: Point) -> bool { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `bool` + | + = note: expected enum `std::result::Result>` + found type `bool` From e66adaa60f44b7c426d2256f2e5f4ac51910d469 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 23:33:42 -0500 Subject: [PATCH 6/6] Revert diagnostic tests which trigger trybuild path bug --- .../ui_tests/rhai_fn_non_clonable_return.rs | 27 ----------------- .../rhai_fn_non_clonable_return.stderr | 10 ------- .../ui_tests/rhai_mod_non_clonable_return.rs | 29 ------------------- .../rhai_mod_non_clonable_return.stderr | 10 ------- 4 files changed, 76 deletions(-) delete mode 100644 codegen/ui_tests/rhai_fn_non_clonable_return.rs delete mode 100644 codegen/ui_tests/rhai_fn_non_clonable_return.stderr delete mode 100644 codegen/ui_tests/rhai_mod_non_clonable_return.rs delete mode 100644 codegen/ui_tests/rhai_mod_non_clonable_return.stderr diff --git a/codegen/ui_tests/rhai_fn_non_clonable_return.rs b/codegen/ui_tests/rhai_fn_non_clonable_return.rs deleted file mode 100644 index e2e2d788..00000000 --- a/codegen/ui_tests/rhai_fn_non_clonable_return.rs +++ /dev/null @@ -1,27 +0,0 @@ -use rhai::plugin::*; - -struct NonClonable { - a: f32, - b: u32, - c: char, - d: bool, -} - -#[export_fn] -pub fn test_fn(input: f32) -> NonClonable { - NonClonable { - a: input, - b: 10, - c: 'a', - d: true, - } -} - -fn main() { - let n = test_fn(20.0); - if n.c == 'a' { - println!("yes"); - } else { - println!("no"); - } -} diff --git a/codegen/ui_tests/rhai_fn_non_clonable_return.stderr b/codegen/ui_tests/rhai_fn_non_clonable_return.stderr deleted file mode 100644 index 6184fd24..00000000 --- a/codegen/ui_tests/rhai_fn_non_clonable_return.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied - --> $DIR/rhai_fn_non_clonable_return.rs:11:8 - | -11 | pub fn test_fn(input: f32) -> NonClonable { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable` - | - ::: /home/cryptkeeper/Desktop/Software/ytdl-replacement/rhai/src/any.rs:537:30 - | -537 | pub fn from(value: T) -> Self { - | ----- required by this bound in `rhai::Dynamic::from` diff --git a/codegen/ui_tests/rhai_mod_non_clonable_return.rs b/codegen/ui_tests/rhai_mod_non_clonable_return.rs deleted file mode 100644 index fe8f5fff..00000000 --- a/codegen/ui_tests/rhai_mod_non_clonable_return.rs +++ /dev/null @@ -1,29 +0,0 @@ -use rhai::plugin::*; - -struct NonClonable { - a: f32, - b: u32, - c: char, - d: bool, -} - -#[export_module] -pub mod test_mod { - pub fn test_fn(input: f32) -> NonClonable { - NonClonable { - a: input, - b: 10, - c: 'a', - d: true, - } - } -} - -fn main() { - let n = test_mod::test_fn(20.0); - if n.c == 'a' { - println!("yes"); - } else { - println!("no"); - } -} diff --git a/codegen/ui_tests/rhai_mod_non_clonable_return.stderr b/codegen/ui_tests/rhai_mod_non_clonable_return.stderr deleted file mode 100644 index db880026..00000000 --- a/codegen/ui_tests/rhai_mod_non_clonable_return.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied - --> $DIR/rhai_mod_non_clonable_return.rs:12:12 - | -12 | pub fn test_fn(input: f32) -> NonClonable { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable` - | - ::: /home/cryptkeeper/Desktop/Software/ytdl-replacement/rhai/src/any.rs:537:30 - | -537 | pub fn from(value: T) -> Self { - | ----- required by this bound in `rhai::Dynamic::from`