diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-10-15 01:39:03 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-10-18 15:56:14 +0200 |
commit | 2a3f93074dd2898669dbbce6e97e5cc4405d7cb1 (patch) | |
tree | 464ad46f18cdc2977291bcb161d0060184767fde | |
parent | 89406d7d7e3dbd3ef33d58b9bf5730d88d718cdf (diff) |
ir: Test on typedefs also for template parameters that are transitively applicable before discarding them.
-rw-r--r-- | src/ir/item.rs | 17 | ||||
-rw-r--r-- | tests/expectations/template_typedef_transitive_param.rs | 18 | ||||
-rw-r--r-- | tests/headers/template_typedef_transitive_param.hpp | 7 |
3 files changed, 41 insertions, 1 deletions
diff --git a/src/ir/item.rs b/src/ir/item.rs index 1647dfe8..5b6297bd 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -167,6 +167,20 @@ impl Item { self.kind().expect_function() } + // This check is needed because even though the type might not contain the + // applicable template args itself, they might apply transitively via, for + // example, the parent. + // + // It's kind of unfortunate (in the sense that it's a sort of complex + // process, but I think it gets all the cases). + fn signature_contains_named_type(&self, ctx: &BindgenContext, ty: &Type) -> bool { + debug_assert!(ty.is_named()); + self.expect_type().signature_contains_named_type(ctx, ty) || + self.applicable_template_args(ctx).iter().any(|template| { + ctx.resolve_type(*template).signature_contains_named_type(ctx, ty) + }) + } + pub fn applicable_template_args(&self, ctx: &BindgenContext) -> Vec<ItemId> { let ty = match *self.kind() { ItemKind::Type(ref ty) => ty, @@ -197,7 +211,8 @@ impl Item { TypeKind::Alias(_, inner) => { let parent_args = ctx.resolve_item(self.parent_id()) .applicable_template_args(ctx); - let inner = ctx.resolve_type(inner); + let inner = ctx.resolve_item(inner); + // Avoid unused type parameters, sigh. parent_args.iter().cloned().filter(|arg| { let arg = ctx.resolve_type(*arg); diff --git a/tests/expectations/template_typedef_transitive_param.rs b/tests/expectations/template_typedef_transitive_param.rs new file mode 100644 index 00000000..166ddc3c --- /dev/null +++ b/tests/expectations/template_typedef_transitive_param.rs @@ -0,0 +1,18 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Wrapper<T> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<T>, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Wrapper_Wrapped<T> { + pub t: T, +} +pub type Wrapper_Type<T> = Wrapper_Wrapped<T>; diff --git a/tests/headers/template_typedef_transitive_param.hpp b/tests/headers/template_typedef_transitive_param.hpp new file mode 100644 index 00000000..2269ac36 --- /dev/null +++ b/tests/headers/template_typedef_transitive_param.hpp @@ -0,0 +1,7 @@ +template<typename T> +struct Wrapper { + struct Wrapped { + T t; + }; + using Type = Wrapped; +}; |