Skip to content

Commit abe5208

Browse files
committed
codegen: Support new-type-alias constants
Fixes #3287
1 parent 1cf0a1f commit abe5208

File tree

5 files changed

+65
-34
lines changed

5 files changed

+65
-34
lines changed

bindgen-integration/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ fn setup_macro_test() {
251251
.blocklist_function("my_prefixed_function_to_remove")
252252
.constified_enum("my_prefixed_enum_to_be_constified")
253253
.opaque_type("my_prefixed_templated_foo<my_prefixed_baz>")
254+
.new_type_alias("MyInt")
255+
.new_type_alias("MyBool")
256+
.new_type_alias("MyFloat")
257+
.new_type_alias("MyChar")
254258
.new_type_alias("TestDeriveOnAlias")
255259
.depfile(out_rust_file_relative.display().to_string(), &out_dep_file)
256260
.generate()

bindgen-integration/cpp/Test.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,16 @@ enum MyOrderedEnum {
246246

247247
// Used to test custom derives on new-type alias. See `test_custom_derive`.
248248
typedef int TestDeriveOnAlias;
249+
250+
// Used to test new-type alias constants. See `test_new_type_alias_const`.
251+
typedef int MyInt;
252+
const MyInt MY_INT = 5;
253+
254+
typedef bool MyBool;
255+
const MyBool MY_BOOL = true;
256+
257+
typedef float MyFloat;
258+
const MyFloat MY_FLOAT = 1.23f;
259+
260+
typedef char MyChar;
261+
const MyChar MY_CHAR = 'a';

bindgen-integration/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,11 @@ fn test_colon_define() {
355355
let gold: u32 = (1u32 << 16) | 2;
356356
assert_eq!(gold, bindings::TESTMACRO_COLON_VALUE);
357357
}
358+
359+
#[test]
360+
fn test_new_type_alias_const() {
361+
assert_eq!(bindings::MY_INT.0, 5);
362+
assert_eq!(bindings::MY_BOOL.0, true);
363+
assert_eq!(bindings::MY_FLOAT.0, 1.23f32);
364+
assert_eq!(bindings::MY_CHAR.0, b'a' as i8);
365+
}

bindgen/codegen/mod.rs

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -680,14 +680,16 @@ impl CodeGenerator for Var {
680680
let var_ty = self.ty();
681681
let ty = var_ty.to_rust_ty_or_opaque(ctx, &());
682682

683+
let var_ty_item = ctx.resolve_item(var_ty);
684+
let alias_style = var_ty_item.alias_style(ctx);
685+
let is_new_type_alias = matches!(
686+
alias_style,
687+
AliasVariation::NewType | AliasVariation::NewTypeDeref
688+
);
689+
683690
if let Some(val) = self.val() {
684-
match *val {
685-
VarType::Bool(val) => {
686-
result.push(quote! {
687-
#(#attrs)*
688-
pub const #canonical_ident : #ty = #val ;
689-
});
690-
}
691+
let const_expr = match *val {
692+
VarType::Bool(val) => Some(val.to_token_stream()),
691693
VarType::Int(val) => {
692694
let int_kind = var_ty
693695
.into_resolver()
@@ -702,10 +704,7 @@ impl CodeGenerator for Var {
702704
} else {
703705
helpers::ast_ty::uint_expr(val as _)
704706
};
705-
result.push(quote! {
706-
#(#attrs)*
707-
pub const #canonical_ident : #ty = #val ;
708-
});
707+
Some(val)
709708
}
710709
VarType::String(ref bytes) => {
711710
let prefix = ctx.trait_prefix();
@@ -758,21 +757,20 @@ impl CodeGenerator for Var {
758757
pub const #canonical_ident: &#(#lifetime )*#array_ty = #bytes ;
759758
});
760759
}
760+
None
761761
}
762-
VarType::Float(f) => {
763-
if let Ok(expr) = helpers::ast_ty::float_expr(f) {
764-
result.push(quote! {
765-
#(#attrs)*
766-
pub const #canonical_ident : #ty = #expr ;
767-
});
768-
}
769-
}
770-
VarType::Char(c) => {
771-
result.push(quote! {
772-
#(#attrs)*
773-
pub const #canonical_ident : #ty = #c ;
774-
});
762+
VarType::Float(f) => helpers::ast_ty::float_expr(f).ok(),
763+
VarType::Char(c) => Some(c.to_token_stream()),
764+
};
765+
766+
if let Some(mut val) = const_expr {
767+
if is_new_type_alias {
768+
val = quote! { #ty(#val) };
775769
}
770+
result.push(quote! {
771+
#(#attrs)*
772+
pub const #canonical_ident : #ty = #val ;
773+
});
776774
}
777775
} else {
778776
let symbol: &str = self.link_name().unwrap_or_else(|| {
@@ -1005,15 +1003,7 @@ impl CodeGenerator for Type {
10051003
quote! {}
10061004
};
10071005

1008-
let alias_style = if ctx.options().type_alias.matches(&name) {
1009-
AliasVariation::TypeAlias
1010-
} else if ctx.options().new_type_alias.matches(&name) {
1011-
AliasVariation::NewType
1012-
} else if ctx.options().new_type_alias_deref.matches(&name) {
1013-
AliasVariation::NewTypeDeref
1014-
} else {
1015-
ctx.options().default_alias_style
1016-
};
1006+
let alias_style = item.alias_style(ctx);
10171007

10181008
// We prefer using `pub use` over `pub type` because of:
10191009
// https://github.com/rust-lang/rust/issues/26264

bindgen/ir/item.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Bindgen's core intermediate representation type.
22
3-
use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME};
3+
use super::super::codegen::{
4+
AliasVariation, EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME,
5+
};
46
use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
57
use super::annotations::Annotations;
68
use super::comp::{CompKind, MethodKind};
@@ -1103,6 +1105,20 @@ impl Item {
11031105
pub(crate) fn must_use(&self, ctx: &BindgenContext) -> bool {
11041106
self.annotations().must_use_type() || ctx.must_use_type_by_name(self)
11051107
}
1108+
1109+
/// Get the alias style for this item.
1110+
pub(crate) fn alias_style(&self, ctx: &BindgenContext) -> AliasVariation {
1111+
let name = self.canonical_name(ctx);
1112+
if ctx.options().type_alias.matches(&name) {
1113+
AliasVariation::TypeAlias
1114+
} else if ctx.options().new_type_alias.matches(&name) {
1115+
AliasVariation::NewType
1116+
} else if ctx.options().new_type_alias_deref.matches(&name) {
1117+
AliasVariation::NewTypeDeref
1118+
} else {
1119+
ctx.options().default_alias_style
1120+
}
1121+
}
11061122
}
11071123

11081124
impl<T> IsOpaque for T

0 commit comments

Comments
 (0)