From 708c0f385e825cb14d66846a804d8c5d007ea416 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Fri, 21 Aug 2020 22:30:10 -0500 Subject: [PATCH] Block #[cfg] attributes on exported or inner functions --- codegen/src/function.rs | 10 ++++++++++ codegen/src/module.rs | 11 +++++++++++ codegen/ui_tests/export_fn_cfg.rs | 25 +++++++++++++++++++++++++ codegen/ui_tests/export_fn_cfg.stderr | 11 +++++++++++ codegen/ui_tests/module_cfg_fn.rs | 27 +++++++++++++++++++++++++++ codegen/ui_tests/module_cfg_fn.stderr | 11 +++++++++++ 6 files changed, 95 insertions(+) create mode 100644 codegen/ui_tests/export_fn_cfg.rs create mode 100644 codegen/ui_tests/export_fn_cfg.stderr create mode 100644 codegen/ui_tests/module_cfg_fn.rs create mode 100644 codegen/ui_tests/module_cfg_fn.stderr diff --git a/codegen/src/function.rs b/codegen/src/function.rs index 0dba5afa..011ff650 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -148,6 +148,16 @@ impl Parse for ExportedFn { let entire_span = fn_all.span(); let str_type_path = syn::parse2::(quote! { str }).unwrap(); + // #[cfg] attributes are not allowed on functions due to what is generated for them + if let Some(cfg_attr) = fn_all.attrs.iter().find(|a| { + a.path + .get_ident() + .map(|i| i.to_string() == "cfg") + .unwrap_or(false) + }) { + return Err(syn::Error::new(cfg_attr.span(), "cfg attributes not allowed on this item")); + } + // Determine if the function is public. let is_public = match fn_all.vis { syn::Visibility::Public(_) => true, diff --git a/codegen/src/module.rs b/codegen/src/module.rs index c6bd6469..d3e09eca 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -16,6 +16,17 @@ use std::borrow::Cow; use std::collections::HashMap; fn inner_fn_attributes(f: &mut syn::ItemFn) -> syn::Result { + // #[cfg] attributes are not allowed on objects + if let Some(cfg_attr) = f.attrs.iter().find(|a| { + a.path + .get_ident() + .map(|i| i.to_string() == "cfg") + .unwrap_or(false) + }) { + return Err(syn::Error::new(cfg_attr.span(), "cfg attributes not allowed on this item")); + } + + // Find the #[rhai_fn] attribute which will turn be read for the function parameters. if let Some(rhai_fn_idx) = f.attrs.iter().position(|a| { a.path .get_ident() diff --git a/codegen/ui_tests/export_fn_cfg.rs b/codegen/ui_tests/export_fn_cfg.rs new file mode 100644 index 00000000..52d4c963 --- /dev/null +++ b/codegen/ui_tests/export_fn_cfg.rs @@ -0,0 +1,25 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[cfg(not(feature = "foo"))] +#[export_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_fn(n) { + println!("yes"); + } else { + println!("no"); + } +} diff --git a/codegen/ui_tests/export_fn_cfg.stderr b/codegen/ui_tests/export_fn_cfg.stderr new file mode 100644 index 00000000..ac068be8 --- /dev/null +++ b/codegen/ui_tests/export_fn_cfg.stderr @@ -0,0 +1,11 @@ +error: cfg attributes not allowed on this item + --> $DIR/export_fn_cfg.rs:9:1 + | +9 | #[cfg(not(feature = "foo"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0425]: cannot find function `test_fn` in this scope + --> $DIR/export_fn_cfg.rs:20:8 + | +20 | if test_fn(n) { + | ^^^^^^^ not found in this scope diff --git a/codegen/ui_tests/module_cfg_fn.rs b/codegen/ui_tests/module_cfg_fn.rs new file mode 100644 index 00000000..3613b9a5 --- /dev/null +++ b/codegen/ui_tests/module_cfg_fn.rs @@ -0,0 +1,27 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + #[cfg(not(feature = "foo"))] + 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/module_cfg_fn.stderr b/codegen/ui_tests/module_cfg_fn.stderr new file mode 100644 index 00000000..80ac12f8 --- /dev/null +++ b/codegen/ui_tests/module_cfg_fn.stderr @@ -0,0 +1,11 @@ +error: cfg attributes not allowed on this item + --> $DIR/module_cfg_fn.rs:11:5 + | +11 | #[cfg(not(feature = "foo"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_module` + --> $DIR/module_cfg_fn.rs:22:8 + | +22 | if test_module::test_fn(n) { + | ^^^^^^^^^^^ use of undeclared type or module `test_module`