Skip to content

Commit b0acd87

Browse files
committed
Allow #[cfg] to be used with #[constant]
1 parent 165afeb commit b0acd87

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

godot-macros/src/class/godot_api.rs

+27-5
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ struct SignalDefinition {
7373
attributes: Vec<Attribute>,
7474
}
7575

76+
/// Holds information known from a constant's definition
77+
struct ConstantDefinition {
78+
constant: Constant,
79+
attributes: Vec<Attribute>,
80+
}
81+
7682
/// Codegen for `#[godot_api] impl MyType`
7783
fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
7884
let class_name = util::validate_impl(&decl, None, "godot_api")?;
@@ -129,16 +135,27 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
129135
.map(|func_def| make_method_registration(&class_name, func_def));
130136

131137
let consts = process_godot_constants(&mut decl)?;
138+
let mut integer_constant_cfg_attrs = Vec::new();
132139
let mut integer_constant_names = Vec::new();
133140
let mut integer_constant_values = Vec::new();
134141

135-
for constant in consts.iter() {
142+
for constant_def in consts.iter() {
143+
let ConstantDefinition {
144+
constant,
145+
attributes,
146+
} = constant_def;
136147
if constant.initializer.is_none() {
137148
return bail!(constant, "exported const should have initializer");
138149
};
139150

140151
let name = &constant.name;
152+
let cfg_attrs = util::extract_cfg_attrs(attributes)
153+
.into_iter()
154+
.collect::<Vec<_>>();
141155

156+
// Transport #[cfg] attrs to the FFI glue to ensure constants which were conditionally
157+
// removed from compilation don't cause errors.
158+
integer_constant_cfg_attrs.push(cfg_attrs);
142159
integer_constant_names.push(constant.name.to_string());
143160
integer_constant_values.push(quote! { #class_name::#name });
144161
}
@@ -150,6 +167,7 @@ fn transform_inherent_impl(mut decl: Impl) -> Result<TokenStream, Error> {
150167
use ::godot::builtin::StringName;
151168

152169
#(
170+
#(#integer_constant_cfg_attrs)*
153171
ExportConstant::new(
154172
#class_name_obj,
155173
ConstantKind::Integer(
@@ -307,15 +325,16 @@ fn process_godot_fns(
307325
Ok((func_definitions, signal_definitions))
308326
}
309327

310-
fn process_godot_constants(decl: &mut Impl) -> Result<Vec<Constant>, Error> {
311-
let mut constant_signatures = vec![];
328+
fn process_godot_constants(decl: &mut Impl) -> Result<Vec<ConstantDefinition>, Error> {
329+
let mut constant_definitions = vec![];
312330

313331
for item in decl.body_items.iter_mut() {
314332
let ImplMember::Constant(constant) = item else {
315333
continue;
316334
};
317335

318336
if let Some(attr) = extract_attributes(&constant, &constant.attributes)? {
337+
let attributes = constant.attributes.clone();
319338
// Remaining code no longer has attribute -- rest stays
320339
constant.attributes.remove(attr.index);
321340

@@ -330,13 +349,16 @@ fn process_godot_constants(decl: &mut Impl) -> Result<Vec<Constant>, Error> {
330349
if constant.initializer.is_none() {
331350
return bail!(constant, "exported constant must have initializer");
332351
}
333-
constant_signatures.push(constant.clone());
352+
constant_definitions.push(ConstantDefinition {
353+
constant: constant.clone(),
354+
attributes,
355+
});
334356
}
335357
}
336358
}
337359
}
338360

339-
Ok(constant_signatures)
361+
Ok(constant_definitions)
340362
}
341363

342364
fn extract_attributes<T>(

itest/rust/src/register_tests/constant_test.rs

+19
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ impl HasConstants {
4040
#[constant]
4141
#[cfg(all())]
4242
const CONSTANT_RECOGNIZED_WITH_SIMPLE_PATH_ATTRIBUTE_BELOW_CONST_ATTR: bool = true;
43+
44+
#[constant]
45+
const CFG_REMOVES_CONSTANT: bool = true;
46+
47+
#[cfg(any())]
48+
#[constant]
49+
const CFG_REMOVES_CONSTANT: bool = false;
50+
51+
#[constant]
52+
#[cfg(any())]
53+
const CFG_REMOVES_CONSTANT: bool = false;
54+
55+
#[cfg(any())]
56+
#[constant]
57+
const CFG_REMOVES_CONSTANT_FFI_GLUE: bool = true;
58+
59+
#[constant]
60+
#[cfg(any())]
61+
const CFG_REMOVES_CONSTANT_FFI_GLUE: bool = true;
4362
}
4463

4564
#[itest]

0 commit comments

Comments
 (0)