Auto merge of #1430 - emilio:implicit-template-params, r=emilio

ir: Consistently append implicit template parameters when not using Rust unions.

Fixes #1429.
diff --git a/Cargo.lock b/Cargo.lock
index f2dd804..71b4134 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,7 +26,7 @@
 
 [[package]]
 name = "bindgen"
-version = "0.43.0"
+version = "0.43.1"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/Cargo.toml b/Cargo.toml
index 4901d78..f5d6627 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,7 +14,7 @@
 repository = "https://github.com/rust-lang-nursery/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
 homepage = "https://rust-lang-nursery.github.io/rust-bindgen/"
-version = "0.43.0"
+version = "0.43.1"
 build = "build.rs"
 
 include = [
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 8cc55a0..d8524a3 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1044,6 +1044,7 @@
         let field_item = self.ty().into_resolver().through_type_refs().resolve(ctx);
         let field_ty = field_item.expect_type();
         let mut ty = self.ty().to_rust_ty_or_opaque(ctx, &());
+        ty.append_implicit_template_params(ctx, field_item);
 
         // NB: If supported, we use proper `union` types.
         let ty = if parent.is_union() && !parent.can_be_rust_union(ctx) {
@@ -1071,7 +1072,6 @@
                 }
             }
         } else {
-            ty.append_implicit_template_params(ctx, field_item);
             ty
         };
 
diff --git a/tests/expectations/tests/transform-op.rs b/tests/expectations/tests/transform-op.rs
new file mode 100644
index 0000000..c3273ca
--- /dev/null
+++ b/tests/expectations/tests/transform-op.rs
@@ -0,0 +1,236 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+    dead_code,
+    non_snake_case,
+    non_camel_case_types,
+    non_upper_case_globals
+)]
+
+#[repr(C)]
+pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
+impl<T> __BindgenUnionField<T> {
+    #[inline]
+    pub fn new() -> Self {
+        __BindgenUnionField(::std::marker::PhantomData)
+    }
+    #[inline]
+    pub unsafe fn as_ref(&self) -> &T {
+        ::std::mem::transmute(self)
+    }
+    #[inline]
+    pub unsafe fn as_mut(&mut self) -> &mut T {
+        ::std::mem::transmute(self)
+    }
+}
+impl<T> ::std::default::Default for __BindgenUnionField<T> {
+    #[inline]
+    fn default() -> Self {
+        Self::new()
+    }
+}
+impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
+    #[inline]
+    fn clone(&self) -> Self {
+        Self::new()
+    }
+}
+impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
+impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+        fmt.write_str("__BindgenUnionField")
+    }
+}
+impl<T> ::std::hash::Hash for __BindgenUnionField<T> {
+    fn hash<H: ::std::hash::Hasher>(&self, _state: &mut H) {}
+}
+impl<T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
+    fn eq(&self, _other: &__BindgenUnionField<T>) -> bool {
+        true
+    }
+}
+impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StylePoint<T> {
+    pub x: T,
+    pub y: T,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StylePoint<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct StyleFoo<T> {
+    pub __bindgen_anon_1: __BindgenUnionField<StyleFoo__bindgen_ty_1>,
+    pub foo: __BindgenUnionField<StyleFoo_Foo_Body<T>>,
+    pub bar: __BindgenUnionField<StyleFoo_Bar_Body<T>>,
+    pub baz: __BindgenUnionField<StyleFoo_Baz_Body<T>>,
+    pub bindgen_union_field: [u8; 0usize],
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+pub const StyleFoo_Tag_Foo: StyleFoo_Tag = 0;
+pub const StyleFoo_Tag_Bar: StyleFoo_Tag = 0;
+pub const StyleFoo_Tag_Baz: StyleFoo_Tag = 0;
+pub const StyleFoo_Tag_Bazz: StyleFoo_Tag = 0;
+pub type StyleFoo_Tag = u8;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleFoo_Foo_Body<T> {
+    pub tag: StyleFoo_Tag,
+    pub x: i32,
+    pub y: StylePoint<T>,
+    pub z: StylePoint<f32>,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleFoo_Foo_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleFoo_Bar_Body<T> {
+    pub tag: StyleFoo_Tag,
+    pub _0: T,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleFoo_Bar_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleFoo_Baz_Body<T> {
+    pub tag: StyleFoo_Tag,
+    pub _0: StylePoint<T>,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleFoo_Baz_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleFoo__bindgen_ty_1 {
+    pub tag: StyleFoo_Tag,
+}
+impl Default for StyleFoo__bindgen_ty_1 {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+impl<T> Default for StyleFoo<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct StyleBar<T> {
+    pub tag: StyleBar_Tag,
+    pub __bindgen_anon_1: StyleBar__bindgen_ty_1<T>,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+pub const StyleBar_Tag_Bar1: StyleBar_Tag = 0;
+pub const StyleBar_Tag_Bar2: StyleBar_Tag = 0;
+pub const StyleBar_Tag_Bar3: StyleBar_Tag = 0;
+pub const StyleBar_Tag_Bar4: StyleBar_Tag = 0;
+pub type StyleBar_Tag = i32;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleBar_StyleBar1_Body<T> {
+    pub x: i32,
+    pub y: StylePoint<T>,
+    pub z: StylePoint<f32>,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleBar_StyleBar1_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleBar_StyleBar2_Body<T> {
+    pub _0: T,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleBar_StyleBar2_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct StyleBar_StyleBar3_Body<T> {
+    pub _0: StylePoint<T>,
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleBar_StyleBar3_Body<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct StyleBar__bindgen_ty_1<T> {
+    pub bar1: __BindgenUnionField<StyleBar_StyleBar1_Body<T>>,
+    pub bar2: __BindgenUnionField<StyleBar_StyleBar2_Body<T>>,
+    pub bar3: __BindgenUnionField<StyleBar_StyleBar3_Body<T>>,
+    pub bindgen_union_field: [u8; 0usize],
+    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+}
+impl<T> Default for StyleBar__bindgen_ty_1<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+impl<T> Default for StyleBar<T> {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+#[test]
+fn __bindgen_test_layout_StylePoint_open0_float_close0_instantiation() {
+    assert_eq!(
+        ::std::mem::size_of::<StylePoint<f32>>(),
+        8usize,
+        concat!(
+            "Size of template specialization: ",
+            stringify!(StylePoint<f32>)
+        )
+    );
+    assert_eq!(
+        ::std::mem::align_of::<StylePoint<f32>>(),
+        4usize,
+        concat!(
+            "Alignment of template specialization: ",
+            stringify!(StylePoint<f32>)
+        )
+    );
+}
+#[test]
+fn __bindgen_test_layout_StylePoint_open0_float_close0_instantiation_1() {
+    assert_eq!(
+        ::std::mem::size_of::<StylePoint<f32>>(),
+        8usize,
+        concat!(
+            "Size of template specialization: ",
+            stringify!(StylePoint<f32>)
+        )
+    );
+    assert_eq!(
+        ::std::mem::align_of::<StylePoint<f32>>(),
+        4usize,
+        concat!(
+            "Alignment of template specialization: ",
+            stringify!(StylePoint<f32>)
+        )
+    );
+}
diff --git a/tests/headers/transform-op.hpp b/tests/headers/transform-op.hpp
new file mode 100644
index 0000000..aa6118e
--- /dev/null
+++ b/tests/headers/transform-op.hpp
@@ -0,0 +1,75 @@
+// bindgen-flags: --rust-target 1.0 -- -std=c++11
+
+typedef unsigned char uint8_t;
+typedef int int32_t;
+
+template<typename T>
+struct StylePoint {
+  T x;
+  T y;
+};
+
+template<typename T>
+union StyleFoo {
+  enum class Tag : uint8_t {
+    Foo,
+    Bar,
+    Baz,
+    Bazz,
+  };
+
+  struct Foo_Body {
+    Tag tag;
+    int32_t x;
+    StylePoint<T> y;
+    StylePoint<float> z;
+  };
+
+  struct Bar_Body {
+    Tag tag;
+    T _0;
+  };
+
+  struct Baz_Body {
+    Tag tag;
+    StylePoint<T> _0;
+  };
+
+  struct {
+    Tag tag;
+  };
+  Foo_Body foo;
+  Bar_Body bar;
+  Baz_Body baz;
+};
+
+template<typename T>
+struct StyleBar {
+  enum class Tag {
+    Bar1,
+    Bar2,
+    Bar3,
+    Bar4,
+  };
+
+  struct StyleBar1_Body {
+    int32_t x;
+    StylePoint<T> y;
+    StylePoint<float> z;
+  };
+
+  struct StyleBar2_Body {
+    T _0;
+  };
+
+  struct StyleBar3_Body {
+    StylePoint<T> _0;
+  };
+
+  Tag tag;
+  union {
+    StyleBar1_Body bar1;
+    StyleBar2_Body bar2;
+    StyleBar3_Body bar3;
+  };
+};