diff options
author | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-03-24 01:14:22 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <ecoal95@gmail.com> | 2016-03-24 01:14:22 +0100 |
commit | d7a3b81d9416c37af5bdb049d5ea222cc0adca15 (patch) | |
tree | 04cca3c9e338d9ca6e9893e2317c10c1a4e52736 | |
parent | 0632095b95231c0ce73c5240d8bae9611e97bc6a (diff) |
gen: Ensure all templates use all of their parameters
-rw-r--r-- | src/gen.rs | 53 | ||||
-rw-r--r-- | tests/headers/template.hpp | 4 |
2 files changed, 34 insertions, 23 deletions
@@ -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); |