Fixing infinite recursion in ConvertTemplateSpecializationType.

Before this CL, a class template with a member function that
refers back to the same class ...

```cpp
    template <typename T>
    struct MyTemplate {
      void MyMethod(const MyTemplate<T>& other) const {}
    };
    using MyTypeAlias = MyTemplate<int>;
```

... would cause an infinite recursion:

```txt
    ...
    Importer::ConvertTemplateSpecializationType() <- importing MyTemplate<int>
    Importer::ConvertType() at importer.cc:746:12
    Importer::ConvertQualType() at importer.cc:767:7
    Importer::ConvertType() at importer.cc:694:5
    Importer::ConvertQualType() at importer.cc:767:7
    FunctionDeclImporter::Import() at function.cc:69:29 <- importing MyMethod
    DeclImporterBase<clang::FunctionDecl>::ImportDecl() ...
    Importer::ImportDecl() at importer.cc:461:26
    Importer::GetDeclItem() at importer.cc:452:38
    Importer::GetItemIdsInSourceOrder() at importer.cc:331:9
    CXXRecordDeclImporter::Import() at cxx_record.cc:137:25
    DeclImporterBase<clang::CXXRecordDecl>::ImportDecl() ...
    Importer::ImportDecl() at importer.cc:461:26
    Importer::GetDeclItem() at importer.cc:452:38
    Importer::ConvertTemplateSpecializationType() <- importing MyTemplate<int>
    ...
```

The problem above was introduced in https://github.com/google/crubit/commit/14732b2920053fadd06917ffd9201cd6d64704ff which started to call
ConvertTemplateSpecializationType from ConvertType (rather than from
TypedefNameDeclImporter::Import which won't be recursively reentered
in this scenario).

This CL prevents the infinite recursion by checking `known_types_` to
check if the `ClassTemplateSpecializationDecl` has been already
processed before.

Interestingly, I've wondered about the infinite recursion before, but
dismissed this problem, because I thought that it is sufficiently tested
via `this` parameter of instance methods (which already had some test
coverage).  It turned out that this coverage is insufficient, because
`method_decl->getThisType()` doesn't use `TemplateSpecializationType`.

PiperOrigin-RevId: 453939417
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 48cd313..f663bbe 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -595,6 +595,9 @@
         type_string));
   }
 
+  if (HasBeenAlreadySuccessfullyImported(specialization_decl))
+    return ConvertTypeDecl(specialization_decl);
+
   if (IsFromCurrentTarget(specialization_decl) &&
       !specialization_decl->isExplicitSpecialization()) {
     // Store implicit `specialization_decl`s so that they will get included in
diff --git a/rs_bindings_from_cc/test/templates/method_params/BUILD b/rs_bindings_from_cc/test/templates/method_params/BUILD
new file mode 100644
index 0000000..96085b3
--- /dev/null
+++ b/rs_bindings_from_cc/test/templates/method_params/BUILD
@@ -0,0 +1,16 @@
+"""End-to-end example of using type aliases to fully-instantiated templates."""
+
+load("@rules_rust//rust:defs.bzl", "rust_test")
+
+licenses(["notice"])
+
+cc_library(
+    name = "method_params",
+    hdrs = ["method_params.h"],
+)
+
+rust_test(
+    name = "main",
+    srcs = ["test.rs"],
+    cc_deps = [":method_params"],
+)
diff --git a/rs_bindings_from_cc/test/templates/method_params/method_params.h b/rs_bindings_from_cc/test/templates/method_params/method_params.h
new file mode 100644
index 0000000..5ef6af7
--- /dev/null
+++ b/rs_bindings_from_cc/test/templates/method_params/method_params.h
@@ -0,0 +1,34 @@
+// 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_TEMPLATES_METHOD_PARAMS_METHOD_PARAMS_H_
+#define THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_TEMPLATES_METHOD_PARAMS_METHOD_PARAMS_H_
+
+#pragma clang lifetime_elision
+
+template <typename T>
+class MyTemplate {
+ public:
+  static MyTemplate Create(T value) {
+    MyTemplate result;
+    result.value_ = value;
+    return result;
+  }
+
+  T AddOneOtherItem(const MyTemplate<T>& other) const {
+    return value_ + other.value_;
+  }
+
+  T AddThreeOtherItems(const MyTemplate<T>& a, const MyTemplate<T>& b,
+                       const MyTemplate<T>& c) const {
+    return value_ + a.value_ + b.value_ + c.value_;
+  }
+
+ private:
+  T value_;
+};
+
+using MyTypeAlias = MyTemplate<int>;
+
+#endif  // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_TEMPLATES_METHOD_PARAMS_METHOD_PARAMS_H_
diff --git a/rs_bindings_from_cc/test/templates/method_params/test.rs b/rs_bindings_from_cc/test/templates/method_params/test.rs
new file mode 100644
index 0000000..633719f
--- /dev/null
+++ b/rs_bindings_from_cc/test/templates/method_params/test.rs
@@ -0,0 +1,31 @@
+// 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
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn test_const_ref_to_self() {
+        // Among other things, this test provides coverage against infinite
+        // recursion around Importer::ConvertTemplateSpecializationType which
+        // in the past might have happened when a member function's parameters
+        // would refer back to the same class template specialization.
+        let s1 = method_params::MyTypeAlias::Create(1);
+        let s2 = method_params::MyTypeAlias::Create(2);
+        assert_eq!(1 + 2, s1.AddOneOtherItem(&s2));
+    }
+
+    fn test_repeating_parameter_type() {
+        // Among other things, this test provides coverage for the (not currently
+        // implemented, but still considered for the future) mangling algorithm
+        // that is required as part of the "Function template" approach from
+        // `thunks_for_class_template_member_functions.md`. In particular,
+        // repeated parameter type should be subject to https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression
+        // (which was missed in the initial prototype of this approach).
+        let s1 = method_params::MyTypeAlias::Create(1);
+        let s2 = method_params::MyTypeAlias::Create(2);
+        let s3 = method_params::MyTypeAlias::Create(3);
+        let s4 = method_params::MyTypeAlias::Create(4);
+        assert_eq!(1 + 2 + 3 + 4, s1.AddThreeOtherItems(&s2, &s3, &s4));
+    }
+}