Make the order of items coming from implicit template specializations deterministic

Currently we sort items in IR according to
1. Source location, and then
2. `Importer::GetDeclOrder()` <- this one ensures that implicit constructors/destructors come in a certain order

Implicit class template specialization decls and their methods have the same source location, which makes the following code snippet problematic:
```
template <typename T>
struct MyStruct {
  void Method(T t);
};

using Alias1 = MyStruct<int>;
using Alias2 = MyStruct<bool>;
```
The generated bindings will contain two structs for the implicit template specializations:
```
pub struct __CcTemplateInst8MyStructIiE {...}
pub struct __CcTemplateInst8MyStructIbE {...}
```
But the order in which they appear is nondeterministic. Same goes for the assertions we generate for these structs, as well as the respective functions in `rs_api_impl.cc`.

This cl addresses the issue by taking into account the mangled name of the class template specialization or function decls when determining the item order.

PiperOrigin-RevId: 456502619
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index f663bbe..107d6da 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -33,6 +33,7 @@
 #include "rs_bindings_from_cc/ir.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/RawCommentList.h"
@@ -227,7 +228,57 @@
   return 999;
 }
 
-class SourceLocationComparator {
+class Importer::SourceOrderKey {
+ public:
+  SourceOrderKey(clang::SourceRange source_range, int decl_order = 0,
+                 std::string name = "")
+      : source_range_(source_range), decl_order_(decl_order), name_(name) {}
+
+  SourceOrderKey(const SourceOrderKey&) = default;
+  SourceOrderKey& operator=(const SourceOrderKey&) = default;
+
+  bool isBefore(const SourceOrderKey& other,
+                const clang::SourceManager& sm) const {
+    if (!source_range_.isValid() || !other.source_range_.isValid()) {
+      if (source_range_.isValid() != other.source_range_.isValid())
+        return !source_range_.isValid() && other.source_range_.isValid();
+    } else {
+      if (source_range_.getBegin() != other.source_range_.getBegin()) {
+        return sm.isBeforeInTranslationUnit(source_range_.getBegin(),
+                                            other.source_range_.getBegin());
+      }
+      if (source_range_.getEnd() != other.source_range_.getEnd()) {
+        return sm.isBeforeInTranslationUnit(source_range_.getEnd(),
+                                            other.source_range_.getEnd());
+      }
+    }
+
+    if (decl_order_ < other.decl_order_) {
+      return true;
+    } else if (decl_order_ > other.decl_order_) {
+      return false;
+    }
+    return name_ < other.name_;
+  }
+
+ private:
+  clang::SourceRange source_range_;
+  int decl_order_;
+  std::string name_;
+};
+
+Importer::SourceOrderKey Importer::GetSourceOrderKey(
+    const clang::Decl* decl) const {
+  return SourceOrderKey(decl->getSourceRange(), GetDeclOrder(decl),
+                        GetNameForSourceOrder(decl));
+}
+
+Importer::SourceOrderKey Importer::GetSourceOrderKey(
+    const clang::RawComment* comment) const {
+  return SourceOrderKey(comment->getSourceRange());
+}
+
+class Importer::SourceLocationComparator {
  public:
   const bool operator()(const clang::SourceLocation& a,
                         const clang::SourceLocation& b) const {
@@ -246,34 +297,19 @@
     return this->operator()(a->getBeginLoc(), b->getBeginLoc());
   }
 
-  using OrderedItemId = std::tuple<clang::SourceRange, int, ItemId>;
-  using OrderedItem = std::tuple<clang::SourceRange, int, IR::Item>;
+  using OrderedItemId = std::pair<SourceOrderKey, ItemId>;
+  using OrderedItem = std::pair<SourceOrderKey, IR::Item>;
 
   template <typename OrderedItemOrId>
   bool operator()(const OrderedItemOrId& a, const OrderedItemOrId& b) const {
-    auto a_range = std::get<0>(a);
-    auto b_range = std::get<0>(b);
-    if (!a_range.isValid() || !b_range.isValid()) {
-      if (a_range.isValid() != b_range.isValid())
-        return !a_range.isValid() && b_range.isValid();
-    } else {
-      if (a_range.getBegin() != b_range.getBegin()) {
-        return sm.isBeforeInTranslationUnit(a_range.getBegin(),
-                                            b_range.getBegin());
-      }
-      if (a_range.getEnd() != b_range.getEnd()) {
-        return sm.isBeforeInTranslationUnit(a_range.getEnd(), b_range.getEnd());
-      }
-    }
-    auto a_decl_order = std::get<1>(a);
-    auto b_decl_order = std::get<1>(b);
-    return a_decl_order < b_decl_order;
+    auto a_source_order = a.first;
+    auto b_source_order = b.first;
+    return a_source_order.isBefore(b_source_order, sm);
   }
-
-  SourceLocationComparator(clang::SourceManager& sm) : sm(sm) {}
+  SourceLocationComparator(const clang::SourceManager& sm) : sm(sm) {}
 
  private:
-  clang::SourceManager& sm;
+  const clang::SourceManager& sm;
 };
 
 std::vector<ItemId> Importer::GetItemIdsInSourceOrder(
@@ -331,7 +367,7 @@
       // redecls, not just the canonical
       if (visited_item_ids.find(item_id) == visited_item_ids.end()) {
         visited_item_ids.insert(item_id);
-        items.push_back({decl->getSourceRange(), GetDeclOrder(decl), item_id});
+        items.push_back({GetSourceOrderKey(decl), item_id});
       }
     }
 
@@ -345,14 +381,14 @@
   }
 
   for (auto& [_, comment] : ordered_comments) {
-    items.push_back({comment->getSourceRange(), 0, GenerateItemId(comment)});
+    items.push_back({GetSourceOrderKey(comment), GenerateItemId(comment)});
   }
   llvm::sort(items, compare_locations);
 
   std::vector<ItemId> ordered_item_ids;
   ordered_item_ids.reserve(items.size());
   for (auto& ordered_item : items) {
-    ordered_item_ids.push_back(std::get<2>(ordered_item));
+    ordered_item_ids.push_back(ordered_item.second);
   }
   return ordered_item_ids;
 }
@@ -362,8 +398,7 @@
   std::vector<SourceLocationComparator::OrderedItemId> items;
   items.reserve(class_template_instantiations_for_current_target_.size());
   for (const auto* decl : class_template_instantiations_for_current_target_) {
-    items.push_back(
-        {decl->getSourceRange(), GetDeclOrder(decl), GenerateItemId(decl)});
+    items.push_back({GetSourceOrderKey(decl), GenerateItemId(decl)});
   }
 
   clang::SourceManager& sm = ctx_.getSourceManager();
@@ -373,7 +408,7 @@
   std::vector<ItemId> ordered_item_ids;
   ordered_item_ids.reserve(items.size());
   for (const auto& ordered_item : items) {
-    ordered_item_ids.push_back(std::get<2>(ordered_item));
+    ordered_item_ids.push_back(ordered_item.second);
   }
   return ordered_item_ids;
 }
@@ -400,7 +435,7 @@
 
   for (auto& comment : comments_) {
     ordered_items.push_back(
-        {comment->getSourceRange(), 0,
+        {GetSourceOrderKey(comment),
          Comment{.text = comment->getFormattedText(sm, sm.getDiagnostics()),
                  .id = GenerateItemId(comment)}});
   }
@@ -412,8 +447,7 @@
           !IsFromCurrentTarget(decl)) {
         continue;
       }
-      ordered_items.push_back(
-          {decl->getSourceRange(), GetDeclOrder(decl), *item});
+      ordered_items.push_back({GetSourceOrderKey(decl), *item});
     }
   }
 
@@ -421,7 +455,7 @@
 
   invocation_.ir_.items.reserve(ordered_items.size());
   for (auto& ordered_item : ordered_items) {
-    invocation_.ir_.items.push_back(std::get<2>(ordered_item));
+    invocation_.ir_.items.push_back(ordered_item.second);
   }
   invocation_.ir_.top_level_item_ids =
       GetItemIdsInSourceOrder(translation_unit_decl);
@@ -847,6 +881,21 @@
   return name;
 }
 
+std::string Importer::GetNameForSourceOrder(const clang::Decl* decl) const {
+  // Implicit class template specializations and their methods all have the
+  // same source location. In order to provide deterministic order of the
+  // respective items in generated source code, we additionally use the
+  // mangled names when sorting the items.
+  if (auto* class_template_specialization_decl =
+          clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(decl)) {
+    return GetMangledName(class_template_specialization_decl);
+  } else if (auto* func_decl = clang::dyn_cast<clang::FunctionDecl>(decl)) {
+    return GetMangledName(func_decl);
+  } else {
+    return "";
+  }
+}
+
 std::optional<UnqualifiedIdentifier> Importer::GetTranslatedName(
     const clang::NamedDecl* named_decl) const {
   switch (named_decl->getDeclName().getNameKind()) {
diff --git a/rs_bindings_from_cc/importer.h b/rs_bindings_from_cc/importer.h
index bc495ac..e7556ad 100644
--- a/rs_bindings_from_cc/importer.h
+++ b/rs_bindings_from_cc/importer.h
@@ -22,6 +22,7 @@
 #include "rs_bindings_from_cc/importers/typedef_name.h"
 #include "rs_bindings_from_cc/ir.h"
 #include "clang/AST/Mangle.h"
+#include "clang/AST/RawCommentList.h"
 
 namespace crubit {
 
@@ -82,6 +83,19 @@
       const clang::TypeDecl* decl) const override;
 
  private:
+  class SourceOrderKey;
+  class SourceLocationComparator;
+
+  // Returns a SourceOrderKey for the given `decl` that should be used for
+  // ordering Items.
+  SourceOrderKey GetSourceOrderKey(const clang::Decl* decl) const;
+  // Returns a SourceOrderKey for the given `comment` that should be used for
+  // ordering Items.
+  SourceOrderKey GetSourceOrderKey(const clang::RawComment* comment) const;
+
+  // Returns a name for `decl` that should be used for ordering declarations.
+  std::string GetNameForSourceOrder(const clang::Decl* decl) const;
+
   // Returns the item ids of template instantiations that have been triggered
   // from the current target.  The returned items are in an arbitrary,
   // deterministic/reproducible order.
diff --git a/rs_bindings_from_cc/ir_from_cc_test.rs b/rs_bindings_from_cc/ir_from_cc_test.rs
index 48eb173..061b641 100644
--- a/rs_bindings_from_cc/ir_from_cc_test.rs
+++ b/rs_bindings_from_cc/ir_from_cc_test.rs
@@ -1070,6 +1070,69 @@
 }
 
 #[test]
+fn test_implicit_specialization_items_are_deterministically_ordered() -> Result<()> {
+    let ir = ir_from_cc(
+        r#" #pragma clang lifetime_elision
+            template <typename T>
+            struct MyStruct {
+              void MyMethod();
+            };
+            struct Str {};
+            using Alias1 = MyStruct<int>;
+            using Alias2 = MyStruct<long long>;
+            using Alias3 = MyStruct<Str>;
+            namespace test_namespace_bindings {
+              using Alias4 = MyStruct<MyStruct<int>>;
+              using Alias5 = MyStruct<bool>;
+            }
+            "#,
+    )?;
+
+    // Implicit class template specializations and their methods all have the same
+    // source location. Test that they are sorted deterministically. (Implementation
+    // detail: the ordering is by mangled name).
+    let class_template_specialization_names = ir
+        .top_level_item_ids()
+        .filter_map(|id| match ir.find_decl(*id).unwrap() {
+            ir::Item::Record(r) if r.rs_name.contains("__CcTemplateInst") => Some(&r.rs_name),
+            _ => None,
+        })
+        .collect_vec();
+    assert_eq!(
+        vec![
+            "__CcTemplateInst8MyStructI3StrE",
+            "__CcTemplateInst8MyStructIS_IiEE",
+            "__CcTemplateInst8MyStructIbE",
+            "__CcTemplateInst8MyStructIiE",
+            "__CcTemplateInst8MyStructIxE"
+        ],
+        class_template_specialization_names
+    );
+
+    let method_mangled_names = ir
+        .functions()
+        .filter_map(|f| match &f.name {
+            UnqualifiedIdentifier::Identifier(id) if id.identifier.as_str() == "MyMethod" => {
+                Some(&f.mangled_name)
+            }
+            _ => None,
+        })
+        .collect_vec();
+    assert_eq!(
+        vec![
+            "_ZN8MyStructI3StrE8MyMethodEv__2f_2ftest_3atesting_5ftarget",
+            "_ZN8MyStructIS_IiEE8MyMethodEv__2f_2ftest_3atesting_5ftarget",
+            "_ZN8MyStructIbE8MyMethodEv__2f_2ftest_3atesting_5ftarget",
+            "_ZN8MyStructIiE8MyMethodEv__2f_2ftest_3atesting_5ftarget",
+            "_ZN8MyStructIxE8MyMethodEv__2f_2ftest_3atesting_5ftarget"
+        ],
+        method_mangled_names
+    );
+
+    Ok(())
+}
+
+#[test]
 fn test_templates_inheritance() -> Result<()> {
     let ir = ir_from_cc(
         r#" #pragma clang lifetime_elision
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 38da128..296dff5 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -5999,4 +5999,77 @@
         );
         Ok(())
     }
+
+    #[test]
+    fn test_implicit_template_specializations_are_sorted_by_mangled_name() -> Result<()> {
+        let bindings = generate_bindings_tokens(&ir_from_cc(
+            r#"
+                template <typename T>
+                struct MyStruct {
+                    T getT();
+                };
+
+                using Alias1 = MyStruct<int>;
+                using Alias2 = MyStruct<double>;
+
+                namespace test_namespace_bindings {
+                    using Alias3 = MyStruct<bool>;
+                }
+                "#,
+        )?)?;
+
+        // Mangled name order: bool < double < int
+        let my_struct_bool = make_rs_ident("__CcTemplateInst8MyStructIbE");
+        let my_struct_double = make_rs_ident("__CcTemplateInst8MyStructIdE");
+        let my_struct_int = make_rs_ident("__CcTemplateInst8MyStructIiE");
+
+        assert_rs_matches!(
+            &bindings.rs_api,
+            quote! {
+                ...
+                pub struct #my_struct_bool {...}
+                ...
+                pub struct #my_struct_double {...}
+                ...
+                pub struct #my_struct_int {...}
+                ...
+                const _: () = assert!(rust_std::mem::size_of::<crate::#my_struct_bool>() == 1);
+                ...
+                const _: () = assert!(rust_std::mem::size_of::<crate::#my_struct_double>() == 1);
+                ...
+                const _: () = assert!(rust_std::mem::size_of::<crate::#my_struct_int>() == 1);
+                ...
+            }
+        );
+
+        // Constructors in mangled name order
+        let my_struct_bool_constructor =
+            make_rs_ident("__rust_thunk___ZN8MyStructIbEC1Ev__2f_2ftest_3atesting_5ftarget");
+        let my_struct_double_constructor =
+            make_rs_ident("__rust_thunk___ZN8MyStructIdEC1Ev__2f_2ftest_3atesting_5ftarget");
+        let my_struct_int_constructor =
+            make_rs_ident("__rust_thunk___ZN8MyStructIiEC1Ev__2f_2ftest_3atesting_5ftarget");
+
+        // User defined methods in mangled name order
+        let my_struct_bool_method =
+            make_rs_ident("__rust_thunk___ZN8MyStructIbE4getTEv__2f_2ftest_3atesting_5ftarget");
+        let my_struct_double_method =
+            make_rs_ident("__rust_thunk___ZN8MyStructIdE4getTEv__2f_2ftest_3atesting_5ftarget");
+        let my_struct_int_method =
+            make_rs_ident("__rust_thunk___ZN8MyStructIiE4getTEv__2f_2ftest_3atesting_5ftarget");
+
+        assert_cc_matches!(
+            &bindings.rs_api_impl,
+            quote! {
+                ...
+                extern "C" void #my_struct_bool_constructor(class MyStruct<bool>*__this) {...} ...
+                extern "C" void #my_struct_double_constructor(class MyStruct<double>*__this) {...} ...
+                extern "C" void #my_struct_int_constructor(class MyStruct<int>*__this) {...} ...
+                extern "C" bool #my_struct_bool_method(class MyStruct<bool>*__this) {...} ...
+                extern "C" double #my_struct_double_method(class MyStruct<double>*__this) {...} ...
+                extern "C" int #my_struct_int_method(class MyStruct<int>*__this) {...} ...
+            }
+        );
+        Ok(())
+    }
 }
diff --git a/rs_bindings_from_cc/test/golden/templates_source_order.h b/rs_bindings_from_cc/test/golden/templates_source_order.h
new file mode 100644
index 0000000..097c5ec
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/templates_source_order.h
@@ -0,0 +1,32 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_SOURCE_ORDER_H_
+#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_SOURCE_ORDER_H_
+
+template <typename T>
+class MyTemplate {
+  T t;
+
+ public:
+  void processT(T t);
+};
+
+struct TopLevel {};
+
+using Alias1 = MyTemplate<int>;
+using Alias2 = MyTemplate<float>;
+using Alias3 = MyTemplate<TopLevel>;
+using Alias4 = MyTemplate<double>;
+using Alias5 = MyTemplate<bool>;
+using Alias6 = MyTemplate<MyTemplate<TopLevel>>;
+
+namespace test_namespace_bindings {
+struct Inner {};
+using Alias7 = MyTemplate<char>;
+using Alias8 = MyTemplate<Inner>;
+using Alias9 = MyTemplate<MyTemplate<Inner>>;
+}  // namespace test_namespace_bindings
+
+#endif  // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_SOURCE_ORDER_H_
diff --git a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs
new file mode 100644
index 0000000..336aa4e
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api.rs
@@ -0,0 +1,678 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// Automatically @generated Rust bindings for C++ target
+// //rs_bindings_from_cc/test/golden:templates_source_order_cc
+#![rustfmt::skip]
+#![feature(const_ptr_offset_from, custom_inner_attributes, negative_impls)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![allow(non_upper_case_globals)]
+#![deny(warnings)]
+
+use ::std as rust_std;
+
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=8
+// Error while generating bindings for item 'MyTemplate':
+// Class templates are not supported yet
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct TopLevel {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(forward_declare::symbol!("TopLevel"), crate::TopLevel);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=16
+// Error while generating bindings for item 'TopLevel::TopLevel':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=16
+// Error while generating bindings for item 'TopLevel::TopLevel':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=16
+// Error while generating bindings for item 'TopLevel::TopLevel':
+// Parameter #0 is not supported: Unsupported type 'struct TopLevel &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=16
+// Error while generating bindings for item 'TopLevel::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=16
+// Error while generating bindings for item 'TopLevel::operator=':
+// Parameter #0 is not supported: Unsupported type 'struct TopLevel &&': Unsupported type: && without lifetime
+
+pub type Alias1 = crate::__CcTemplateInst10MyTemplateIiE;
+
+pub type Alias2 = crate::__CcTemplateInst10MyTemplateIfE;
+
+pub type Alias3 = crate::__CcTemplateInst10MyTemplateI8TopLevelE;
+
+pub type Alias4 = crate::__CcTemplateInst10MyTemplateIdE;
+
+pub type Alias5 = crate::__CcTemplateInst10MyTemplateIbE;
+
+pub type Alias6 = crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE;
+
+pub mod test_namespace_bindings {
+    #[ctor::recursively_pinned]
+    #[repr(C)]
+    pub struct Inner {
+        __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+    }
+    forward_declare::unsafe_define!(
+        forward_declare::symbol!("Inner"),
+        crate::test_namespace_bindings::Inner
+    );
+
+    // rs_bindings_from_cc/test/golden/templates_source_order.h;l=26
+    // Error while generating bindings for item 'Inner::Inner':
+    // Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+    // rs_bindings_from_cc/test/golden/templates_source_order.h;l=26
+    // Error while generating bindings for item 'Inner::Inner':
+    // Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+    // rs_bindings_from_cc/test/golden/templates_source_order.h;l=26
+    // Error while generating bindings for item 'test_namespace_bindings::Inner::Inner':
+    // Parameter #0 is not supported: Unsupported type 'struct test_namespace_bindings::Inner &&': Unsupported type: && without lifetime
+
+    // rs_bindings_from_cc/test/golden/templates_source_order.h;l=26
+    // Error while generating bindings for item 'Inner::operator=':
+    // `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+    // rs_bindings_from_cc/test/golden/templates_source_order.h;l=26
+    // Error while generating bindings for item 'test_namespace_bindings::Inner::operator=':
+    // Parameter #0 is not supported: Unsupported type 'struct test_namespace_bindings::Inner &&': Unsupported type: && without lifetime
+
+    pub type Alias7 = crate::__CcTemplateInst10MyTemplateIcE;
+
+    pub type Alias8 = crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE;
+
+    pub type Alias9 = crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE;
+}
+
+// namespace test_namespace_bindings
+
+// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_SOURCE_ORDER_H_
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateI8TopLevelE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<TopLevel>"),
+    crate::__CcTemplateInst10MyTemplateI8TopLevelE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<TopLevel>::MyTemplate<TopLevel>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<TopLevel>::MyTemplate<TopLevel>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<TopLevel>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<struct TopLevel> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<TopLevel>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<TopLevel>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<struct TopLevel> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateI8TopLevelE {
+    #[inline(always)]
+    pub unsafe fn processT(
+        __this: *mut crate::__CcTemplateInst10MyTemplateI8TopLevelE,
+        t: crate::TopLevel,
+    ) {
+        crate::detail::__rust_thunk___ZN10MyTemplateI8TopLevelE8processTES0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<test_namespace_bindings::Inner>"),
+    crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<test_namespace_bindings::Inner>::MyTemplate<test_namespace_bindings::Inner>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<test_namespace_bindings::Inner>::MyTemplate<test_namespace_bindings::Inner>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<test_namespace_bindings::Inner>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<struct test_namespace_bindings::Inner> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<test_namespace_bindings::Inner>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<test_namespace_bindings::Inner>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<struct test_namespace_bindings::Inner> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE {
+    #[inline(always)]
+    pub unsafe fn processT(
+        __this: *mut crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE,
+        t: crate::test_namespace_bindings::Inner,
+    ) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateIS_I8TopLevelEE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<MyTemplate<TopLevel>>"),
+    crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<TopLevel>>::MyTemplate<MyTemplate<TopLevel>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<TopLevel>>::MyTemplate<MyTemplate<TopLevel>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<TopLevel>>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<class MyTemplate<struct TopLevel> > &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<TopLevel>>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<TopLevel>>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<class MyTemplate<struct TopLevel> > &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIS_I8TopLevelEE {
+    #[inline(always)]
+    pub unsafe fn processT(
+        __this: *mut crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE,
+        t: crate::__CcTemplateInst10MyTemplateI8TopLevelE,
+    ) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIS_I8TopLevelEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<MyTemplate<test_namespace_bindings::Inner>>"),
+    crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<test_namespace_bindings::Inner>>::MyTemplate<MyTemplate<test_namespace_bindings::Inner>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<test_namespace_bindings::Inner>>::MyTemplate<MyTemplate<test_namespace_bindings::Inner>>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<test_namespace_bindings::Inner>>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<class MyTemplate<struct test_namespace_bindings::Inner> > &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<test_namespace_bindings::Inner>>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<MyTemplate<test_namespace_bindings::Inner>>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<class MyTemplate<struct test_namespace_bindings::Inner> > &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE {
+    #[inline(always)]
+    pub unsafe fn processT(
+        __this: *mut crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE,
+        t: crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE,
+    ) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEE8processTES2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateIbE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<bool>"),
+    crate::__CcTemplateInst10MyTemplateIbE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<bool>::MyTemplate<bool>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<bool>::MyTemplate<bool>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<bool>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<_Bool> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<bool>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<bool>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<_Bool> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIbE {
+    #[inline(always)]
+    pub unsafe fn processT(__this: *mut crate::__CcTemplateInst10MyTemplateIbE, t: bool) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIbE8processTEb__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C)]
+pub struct __CcTemplateInst10MyTemplateIcE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 1],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<char>"),
+    crate::__CcTemplateInst10MyTemplateIcE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<char>::MyTemplate<char>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<char>::MyTemplate<char>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<char>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<char> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<char>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<char>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<char> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIcE {
+    #[inline(always)]
+    pub unsafe fn processT(__this: *mut crate::__CcTemplateInst10MyTemplateIcE, t: u8) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIcE8processTEc__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C, align(8))]
+pub struct __CcTemplateInst10MyTemplateIdE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 8],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<double>"),
+    crate::__CcTemplateInst10MyTemplateIdE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<double>::MyTemplate<double>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<double>::MyTemplate<double>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<double>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<double> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<double>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<double>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<double> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIdE {
+    #[inline(always)]
+    pub unsafe fn processT(__this: *mut crate::__CcTemplateInst10MyTemplateIdE, t: f64) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIdE8processTEd__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C, align(4))]
+pub struct __CcTemplateInst10MyTemplateIfE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 4],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<float>"),
+    crate::__CcTemplateInst10MyTemplateIfE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<float>::MyTemplate<float>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<float>::MyTemplate<float>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<float>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<float> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<float>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<float>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<float> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIfE {
+    #[inline(always)]
+    pub unsafe fn processT(__this: *mut crate::__CcTemplateInst10MyTemplateIfE, t: f32) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIfE8processTEf__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+#[ctor::recursively_pinned]
+#[repr(C, align(4))]
+pub struct __CcTemplateInst10MyTemplateIiE {
+    __non_field_data: [crate::rust_std::mem::MaybeUninit<u8>; 0],
+    /// Reason for representing this field as a blob of bytes:
+    /// Types of non-public C++ fields can be elided away
+    pub(crate) t: [crate::rust_std::mem::MaybeUninit<u8>; 4],
+}
+forward_declare::unsafe_define!(
+    forward_declare::symbol!("MyTemplate<int>"),
+    crate::__CcTemplateInst10MyTemplateIiE
+);
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<int>::MyTemplate<int>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<int>::MyTemplate<int>':
+// Unsafe constructors (e.g. with no elided or explicit lifetimes) are intentionally not supported
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<int>::MyTemplate':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<int> &&': Unsupported type: && without lifetime
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<int>::operator=':
+// `self` has no lifetime. Use lifetime annotations or `#pragma clang lifetime_elision` to create bindings for this function.
+
+// rs_bindings_from_cc/test/golden/templates_source_order.h;l=9
+// Error while generating bindings for item 'MyTemplate<int>::operator=':
+// Parameter #0 is not supported: Unsupported type 'class MyTemplate<int> &&': Unsupported type: && without lifetime
+
+impl __CcTemplateInst10MyTemplateIiE {
+    #[inline(always)]
+    pub unsafe fn processT(__this: *mut crate::__CcTemplateInst10MyTemplateIiE, t: i32) {
+        crate::detail::__rust_thunk___ZN10MyTemplateIiE8processTEi__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(__this,t)
+    }
+}
+
+mod detail {
+    #[allow(unused_imports)]
+    use super::*;
+    extern "C" {
+        pub(crate) fn __rust_thunk___ZN10MyTemplateI8TopLevelE8processTES0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateI8TopLevelE,
+            t: crate::TopLevel,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE,
+            t: crate::test_namespace_bindings::Inner,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIS_I8TopLevelEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE,
+            t: crate::__CcTemplateInst10MyTemplateI8TopLevelE,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEE8processTES2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE,
+            t: crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIbE8processTEb__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIbE,
+            t: bool,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIcE8processTEc__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIcE,
+            t: u8,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIdE8processTEd__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIdE,
+            t: f64,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIfE8processTEf__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIfE,
+            t: f32,
+        );
+        pub(crate) fn __rust_thunk___ZN10MyTemplateIiE8processTEi__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+            __this: *mut crate::__CcTemplateInst10MyTemplateIiE,
+            t: i32,
+        );
+    }
+}
+
+const _: () = assert!(rust_std::mem::size_of::<Option<&i32>>() == rust_std::mem::size_of::<&i32>());
+
+const _: () = assert!(rust_std::mem::size_of::<crate::TopLevel>() == 1);
+const _: () = assert!(rust_std::mem::align_of::<crate::TopLevel>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::TopLevel: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::TopLevel: Drop);
+};
+
+const _: () = assert!(rust_std::mem::size_of::<crate::test_namespace_bindings::Inner>() == 1);
+const _: () = assert!(rust_std::mem::align_of::<crate::test_namespace_bindings::Inner>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::test_namespace_bindings::Inner: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::test_namespace_bindings::Inner: Drop);
+};
+
+const _: () =
+    assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateI8TopLevelE>() == 1);
+const _: () =
+    assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateI8TopLevelE>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateI8TopLevelE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateI8TopLevelE: Drop);
+};
+const _: () = assert!(
+    memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateI8TopLevelE, t) == 0
+);
+
+const _: () = assert!(
+    rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE>(
+    ) == 1
+);
+const _: () = assert!(
+    rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE>(
+    ) == 1
+);
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE: Copy
+    );
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE: Drop
+    );
+};
+const _: () = assert!(
+    memoffset_unstable_const::offset_of!(
+        crate::__CcTemplateInst10MyTemplateIN23test_namespace_bindings5InnerEE,
+        t
+    ) == 0
+);
+
+const _: () =
+    assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE>() == 1);
+const _: () =
+    assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE: Copy
+    );
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE: Drop
+    );
+};
+const _: () = assert!(
+    memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIS_I8TopLevelEE, t)
+        == 0
+);
+
+const _: () = assert!(
+    rust_std::mem::size_of::<
+        crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE,
+    >() == 1
+);
+const _: () = assert!(
+    rust_std::mem::align_of::<
+        crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE,
+    >() == 1
+);
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE: Copy
+    );
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(
+        crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE: Drop
+    );
+};
+const _: () = assert!(
+    memoffset_unstable_const::offset_of!(
+        crate::__CcTemplateInst10MyTemplateIS_IN23test_namespace_bindings5InnerEEE,
+        t
+    ) == 0
+);
+
+const _: () = assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIbE>() == 1);
+const _: () = assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIbE>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIbE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIbE: Drop);
+};
+const _: () =
+    assert!(memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIbE, t) == 0);
+
+const _: () = assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIcE>() == 1);
+const _: () = assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIcE>() == 1);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIcE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIcE: Drop);
+};
+const _: () =
+    assert!(memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIcE, t) == 0);
+
+const _: () = assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIdE>() == 8);
+const _: () = assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIdE>() == 8);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIdE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIdE: Drop);
+};
+const _: () =
+    assert!(memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIdE, t) == 0);
+
+const _: () = assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIfE>() == 4);
+const _: () = assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIfE>() == 4);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIfE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIfE: Drop);
+};
+const _: () =
+    assert!(memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIfE, t) == 0);
+
+const _: () = assert!(rust_std::mem::size_of::<crate::__CcTemplateInst10MyTemplateIiE>() == 4);
+const _: () = assert!(rust_std::mem::align_of::<crate::__CcTemplateInst10MyTemplateIiE>() == 4);
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIiE: Copy);
+};
+const _: () = {
+    static_assertions::assert_not_impl_all!(crate::__CcTemplateInst10MyTemplateIiE: Drop);
+};
+const _: () =
+    assert!(memoffset_unstable_const::offset_of!(crate::__CcTemplateInst10MyTemplateIiE, t) == 0);
diff --git a/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc
new file mode 100644
index 0000000..eda9690
--- /dev/null
+++ b/rs_bindings_from_cc/test/golden/templates_source_order_rs_api_impl.cc
@@ -0,0 +1,325 @@
+// Part of the Crubit project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include <cstddef>
+#include <memory>
+
+#include "rs_bindings_from_cc/support/cxx20_backports.h"
+#include "rs_bindings_from_cc/support/offsetof.h"
+#include "rs_bindings_from_cc/test/golden/templates_source_order.h"
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wthread-safety-analysis"
+extern "C" void
+__rust_thunk___ZN10MyTemplateI8TopLevelEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<TopLevel>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<test_namespace_bindings::Inner>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_I8TopLevelEEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<TopLevel>>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIbEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<bool>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIcEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<char>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIdEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<double>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIfEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<float>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIiEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<int>* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateI8TopLevelEC1ERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<TopLevel>* __this,
+    const class MyTemplate<TopLevel>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEEC1ERKS2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<test_namespace_bindings::Inner>* __this,
+    const class MyTemplate<test_namespace_bindings::Inner>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_I8TopLevelEEC1ERKS2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<TopLevel>>* __this,
+    const class MyTemplate<MyTemplate<TopLevel>>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEEC1ERKS3___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>* __this,
+    const class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>&
+        __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIbEC1ERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<bool>* __this, const class MyTemplate<bool>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIcEC1ERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<char>* __this, const class MyTemplate<char>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIdEC1ERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<double>* __this,
+    const class MyTemplate<double>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIfEC1ERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<float>* __this, const class MyTemplate<float>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIiEC1ERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<int>* __this, const class MyTemplate<int>& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateI8TopLevelED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<TopLevel>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<test_namespace_bindings::Inner>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_I8TopLevelEED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<TopLevel>>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIbED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<bool>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIcED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<char>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIdED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<double>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIfED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<float>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIiED1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<int>* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" class MyTemplate<TopLevel>&
+__rust_thunk___ZN10MyTemplateI8TopLevelEaSERKS1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<TopLevel>* __this,
+    const class MyTemplate<TopLevel>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<test_namespace_bindings::Inner>&
+__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEEaSERKS2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<test_namespace_bindings::Inner>* __this,
+    const class MyTemplate<test_namespace_bindings::Inner>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<MyTemplate<TopLevel>>&
+__rust_thunk___ZN10MyTemplateIS_I8TopLevelEEaSERKS2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<TopLevel>>* __this,
+    const class MyTemplate<MyTemplate<TopLevel>>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>&
+__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEEaSERKS3___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>* __this,
+    const class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>&
+        __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<bool>&
+__rust_thunk___ZN10MyTemplateIbEaSERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<bool>* __this, const class MyTemplate<bool>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<char>&
+__rust_thunk___ZN10MyTemplateIcEaSERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<char>* __this, const class MyTemplate<char>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<double>&
+__rust_thunk___ZN10MyTemplateIdEaSERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<double>* __this,
+    const class MyTemplate<double>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<float>&
+__rust_thunk___ZN10MyTemplateIfEaSERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<float>* __this, const class MyTemplate<float>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" class MyTemplate<int>&
+__rust_thunk___ZN10MyTemplateIiEaSERKS0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<int>* __this, const class MyTemplate<int>& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+} extern "C" void
+__rust_thunk___ZN10MyTemplateI8TopLevelE8processTES0___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<TopLevel>* __this, class TopLevel t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIN23test_namespace_bindings5InnerEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<test_namespace_bindings::Inner>* __this,
+    class test_namespace_bindings::Inner t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_I8TopLevelEE8processTES1___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<TopLevel>>* __this,
+    class MyTemplate<TopLevel> t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIS_IN23test_namespace_bindings5InnerEEE8processTES2___2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>* __this,
+    class MyTemplate<test_namespace_bindings::Inner> t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIbE8processTEb__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<bool>* __this, bool t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIcE8processTEc__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<char>* __this, char t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIdE8processTEd__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<double>* __this, double t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIfE8processTEf__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<float>* __this, float t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void
+__rust_thunk___ZN10MyTemplateIiE8processTEi__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fsource_5forder_5fcc(
+    class MyTemplate<int>* __this, int t) {
+  __this->processT(std::forward<decltype(t)>(t));
+}
+extern "C" void __rust_thunk___ZN8TopLevelC1Ev(class TopLevel* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void __rust_thunk___ZN8TopLevelC1ERKS_(
+    class TopLevel* __this, const class TopLevel& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void __rust_thunk___ZN8TopLevelD1Ev(class TopLevel* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" class TopLevel& __rust_thunk___ZN8TopLevelaSERKS_(
+    class TopLevel* __this, const class TopLevel& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void __rust_thunk___ZN23test_namespace_bindings5InnerC1Ev(
+    class test_namespace_bindings::Inner* __this) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" void __rust_thunk___ZN23test_namespace_bindings5InnerC1ERKS0_(
+    class test_namespace_bindings::Inner* __this,
+    const class test_namespace_bindings::Inner& __param_0) {
+  crubit::construct_at(std::forward<decltype(__this)>(__this),
+                       std::forward<decltype(__param_0)>(__param_0));
+}
+extern "C" void __rust_thunk___ZN23test_namespace_bindings5InnerD1Ev(
+    class test_namespace_bindings::Inner* __this) {
+  std::destroy_at(std::forward<decltype(__this)>(__this));
+}
+extern "C" class test_namespace_bindings::Inner&
+__rust_thunk___ZN23test_namespace_bindings5InneraSERKS0_(
+    class test_namespace_bindings::Inner* __this,
+    const class test_namespace_bindings::Inner& __param_0) {
+  return __this->operator=(std::forward<decltype(__param_0)>(__param_0));
+}
+
+static_assert(sizeof(class MyTemplate<TopLevel>) == 1);
+static_assert(alignof(class MyTemplate<TopLevel>) == 1);
+
+static_assert(sizeof(class MyTemplate<test_namespace_bindings::Inner>) == 1);
+static_assert(alignof(class MyTemplate<test_namespace_bindings::Inner>) == 1);
+
+static_assert(sizeof(class MyTemplate<MyTemplate<TopLevel>>) == 1);
+static_assert(alignof(class MyTemplate<MyTemplate<TopLevel>>) == 1);
+
+static_assert(
+    sizeof(class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>) == 1);
+static_assert(
+    alignof(class MyTemplate<MyTemplate<test_namespace_bindings::Inner>>) == 1);
+
+static_assert(sizeof(class MyTemplate<bool>) == 1);
+static_assert(alignof(class MyTemplate<bool>) == 1);
+
+static_assert(sizeof(class MyTemplate<char>) == 1);
+static_assert(alignof(class MyTemplate<char>) == 1);
+
+static_assert(sizeof(class MyTemplate<double>) == 8);
+static_assert(alignof(class MyTemplate<double>) == 8);
+
+static_assert(sizeof(class MyTemplate<float>) == 4);
+static_assert(alignof(class MyTemplate<float>) == 4);
+
+static_assert(sizeof(class MyTemplate<int>) == 4);
+static_assert(alignof(class MyTemplate<int>) == 4);
+
+static_assert(sizeof(class TopLevel) == 1);
+static_assert(alignof(class TopLevel) == 1);
+
+static_assert(sizeof(class test_namespace_bindings::Inner) == 1);
+static_assert(alignof(class test_namespace_bindings::Inner) == 1);
+
+#pragma clang diagnostic pop