summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <ecoal95@gmail.com>2016-03-24 01:14:22 +0100
committerEmilio Cobos Álvarez <ecoal95@gmail.com>2016-03-24 01:14:22 +0100
commitd7a3b81d9416c37af5bdb049d5ea222cc0adca15 (patch)
tree04cca3c9e338d9ca6e9893e2317c10c1a4e52736
parent0632095b95231c0ce73c5240d8bae9611e97bc6a (diff)
gen: Ensure all templates use all of their parameters
-rw-r--r--src/gen.rs53
-rw-r--r--tests/headers/template.hpp4
2 files changed, 34 insertions, 23 deletions
diff --git a/src/gen.rs b/src/gen.rs
index bfe06c39..882d58e7 100644
--- a/src/gen.rs
+++ b/src/gen.rs
@@ -953,27 +953,10 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
}
}
- if members.is_empty() {
- let mut phantom_count = 0;
- for arg in template_args {
- let f_name = format!("_phantom{}", phantom_count);
- phantom_count += 1;
- let inner_type = P(cty_to_rs(ctx, &arg, true, false));
- fields.push(respan(ctx.span, ast::StructField_ {
- kind: ast::NamedField(
- ctx.ext_cx.ident_of(&f_name),
- ast::Visibility::Public,
- ),
- id: ast::DUMMY_NODE_ID,
- ty: quote_ty!(&ctx.ext_cx, ::std::marker::PhantomData<$inner_type>),
- attrs: vec!(),
- }));
- }
- }
-
let mut anon_enum_count = 0;
let mut setters = vec!();
let mut has_destructor = ci.has_destructor;
+ let mut template_args_used = vec![false; template_args.len()];
for m in members.iter() {
if let CompMember::Enum(ref ei) = *m {
@@ -1065,13 +1048,20 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
};
// If the member is not a template argument, it needs the full path.
- let needs_full_path = !template_args.iter().any(|arg| {
- f_ty == *arg || match f_ty {
+ let mut needs_full_path = true;
+ for (index, arg) in template_args.iter().enumerate() {
+ let used = f_ty == *arg || match f_ty {
TPtr(ref t, _, _, _) => **t == *arg,
TArray(ref t, _, _) => **t == *arg,
_ => false,
+ };
+ if used {
+ template_args_used[index] = true;
+ needs_full_path = false;
+ break;
}
- });
+ }
+
let f_ty = P(cty_to_rs(ctx, &f_ty, f.bitfields.is_none(), needs_full_path));
fields.push(respan(ctx.span, ast::StructField_ {
@@ -1106,6 +1096,27 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
}
}
}
+
+ let mut phantom_count = 0;
+ for (i, arg) in template_args.iter().enumerate() {
+ if template_args_used[i] {
+ continue;
+ }
+
+ let f_name = format!("_phantom{}", phantom_count);
+ phantom_count += 1;
+ let inner_type = P(cty_to_rs(ctx, &arg, true, false));
+ fields.push(respan(ctx.span, ast::StructField_ {
+ kind: ast::NamedField(
+ ctx.ext_cx.ident_of(&f_name),
+ ast::Visibility::Public,
+ ),
+ id: ast::DUMMY_NODE_ID,
+ ty: quote_ty!(&ctx.ext_cx, ::std::marker::PhantomData<$inner_type>),
+ attrs: vec!(),
+ }));
+ }
+
if !setters.is_empty() {
extra.push(P(ast::Item {
ident: ctx.ext_cx.ident_of(""),
diff --git a/tests/headers/template.hpp b/tests/headers/template.hpp
index f9483faa..d25d512f 100644
--- a/tests/headers/template.hpp
+++ b/tests/headers/template.hpp
@@ -1,7 +1,7 @@
-template<typename T> class Foo {
+template<typename T, typename U> class Foo {
T m_member;
T* m_member_ptr;
T m_member_arr[1];
};
-void bar(Foo<int> foo);
+void bar(Foo<int, int> foo);