From 525ffe6f5a8db5990d1c11be33bd09614ede8a41 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Thu, 27 Aug 2020 22:26:05 -0500 Subject: [PATCH] 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"); + } +}