diff --git a/godot-macros/src/class/godot_api.rs b/godot-macros/src/class/godot_api.rs index 11424c647..5b4531ab0 100644 --- a/godot-macros/src/class/godot_api.rs +++ b/godot-macros/src/class/godot_api.rs @@ -136,6 +136,7 @@ fn transform_inherent_impl(mut decl: Impl) -> Result { .map(|func_def| make_method_registration(&class_name, func_def)); let consts = process_godot_constants(&mut decl)?; + let mut integer_constant_cfg_attrs = Vec::new(); let mut integer_constant_names = Vec::new(); let mut integer_constant_values = Vec::new(); @@ -146,6 +147,15 @@ fn transform_inherent_impl(mut decl: Impl) -> Result { let name = &constant.name; + // Unlike with #[func] and #[signal], we don't remove the attributes from Constant + // signatures within 'process_godot_constants'. + let cfg_attrs = util::extract_cfg_attrs(&constant.attributes) + .into_iter() + .collect::>(); + + // Transport #[cfg] attrs to the FFI glue to ensure constants which were conditionally + // removed from compilation don't cause errors. + integer_constant_cfg_attrs.push(cfg_attrs); integer_constant_names.push(constant.name.to_string()); integer_constant_values.push(quote! { #class_name::#name }); } @@ -157,6 +167,7 @@ fn transform_inherent_impl(mut decl: Impl) -> Result { use ::godot::builtin::StringName; #( + #(#integer_constant_cfg_attrs)* ExportConstant::new( #class_name_obj, ConstantKind::Integer( diff --git a/itest/rust/src/register_tests/constant_test.rs b/itest/rust/src/register_tests/constant_test.rs index c671de9c4..d23fd39e6 100644 --- a/itest/rust/src/register_tests/constant_test.rs +++ b/itest/rust/src/register_tests/constant_test.rs @@ -40,15 +40,35 @@ impl HasConstants { #[constant] #[cfg(all())] const CONSTANT_RECOGNIZED_WITH_SIMPLE_PATH_ATTRIBUTE_BELOW_CONST_ATTR: bool = true; + + #[constant] + const CFG_REMOVES_CONSTANT: i64 = 5; + + #[cfg(any())] + #[constant] + const CFG_REMOVES_CONSTANT: i64 = 10; + + #[constant] + #[cfg(any())] + const CFG_REMOVES_CONSTANT: i64 = 10; + + #[cfg(any())] + #[constant] + const CFG_REMOVES_CONSTANT_FFI_GLUE: bool = true; + + #[constant] + #[cfg(any())] + const CFG_REMOVES_CONSTANT_FFI_GLUE: bool = true; } #[itest] fn constants_correct_value() { - const CONSTANTS: [(&str, i64); 4] = [ + const CONSTANTS: [(&str, i64); 5] = [ ("A", HasConstants::A), ("B", HasConstants::B as i64), ("C", HasConstants::C as i64), ("D", HasConstants::D as i64), + ("CFG_REMOVES_CONSTANT", HasConstants::CFG_REMOVES_CONSTANT), ]; let constants = ClassDb::singleton() @@ -72,6 +92,17 @@ fn constants_correct_value() { static_assert!(HasConstants::CONSTANT_RECOGNIZED_WITH_SIMPLE_PATH_ATTRIBUTE_BELOW_CONST_ATTR); } +#[itest] +fn cfg_removes_or_keeps_constants() { + let has_constant = |name: &str| { + ClassDb::singleton() + .class_has_integer_constant(HasConstants::class_name().to_string_name(), name.into()) + }; + + assert!(has_constant("CFG_REMOVES_CONSTANT")); + assert!(!has_constant("CFG_REMOVES_CONSTANT_FFI_GLUE")); +} + #[derive(GodotClass)] struct HasOtherConstants {}