diff --git a/codegen/src/module.rs b/codegen/src/module.rs index 7aa98409..34b67876 100644 --- a/codegen/src/module.rs +++ b/codegen/src/module.rs @@ -199,7 +199,7 @@ impl Parse for Module { fn parse(input: ParseStream) -> syn::Result { let mut mod_all: syn::ItemMod = input.parse()?; let fns: Vec<_>; - let consts: Vec<_>; + let mut consts: Vec<_> = new_vec![]; let mut submodules: Vec<_> = Vec::new(); if let Some((_, ref mut content)) = mod_all.content { // Gather and parse functions. @@ -223,24 +223,33 @@ impl Parse for Module { .map(|_| vec) })?; // Gather and parse constants definitions. - consts = content - .iter() - .filter_map(|item| match item { + for item in content.iter() { + match item { syn::Item::Const(syn::ItemConst { vis, ref expr, ident, + attrs, .. }) => { - if let syn::Visibility::Public(_) = vis { - Some((ident.to_string(), expr.as_ref().clone())) - } else { - None + // #[cfg] attributes are not allowed on const declarations + if let Some(cfg_attr) = 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")); } - } - _ => None, - }) - .collect(); + if let syn::Visibility::Public(_) = vis { + consts.push((ident.to_string(), expr.as_ref().clone())); + } + }, + _ => {}, + } + }; // Gather and parse submodule definitions. // // They are actually removed from the module's body, because they will need @@ -270,7 +279,6 @@ impl Parse for Module { } } } else { - consts = new_vec![]; fns = new_vec![]; } Ok(Module { diff --git a/codegen/ui_tests/module_cfg_const.rs b/codegen/ui_tests/module_cfg_const.rs new file mode 100644 index 00000000..599f52da --- /dev/null +++ b/codegen/ui_tests/module_cfg_const.rs @@ -0,0 +1,31 @@ +use rhai::plugin::*; + +#[derive(Clone)] +pub struct Point { + x: f32, + y: f32, +} + +#[export_module] +pub mod test_module { + use rhai::FLOAT; + + #[cfg(feature = "foo")] + pub const MAGIC: FLOAT = 42.0 as FLOAT; + + 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_const.stderr b/codegen/ui_tests/module_cfg_const.stderr new file mode 100644 index 00000000..4eaf1b06 --- /dev/null +++ b/codegen/ui_tests/module_cfg_const.stderr @@ -0,0 +1,11 @@ +error: cfg attributes not allowed on this item + --> $DIR/module_cfg_const.rs:13:5 + | +13 | #[cfg(feature = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type or module `test_module` + --> $DIR/module_cfg_const.rs:26:8 + | +26 | if test_module::test_fn(n) { + | ^^^^^^^^^^^ use of undeclared type or module `test_module`