s/ `String` / `Rc<str>` / in `NamespaceQualifier` and `ir::Identifier`.

This CL was motivated by trying to improve the efficiency of
`NamespaceQualifier`'s `Clone` implementation - cloning of `Rc<str>`
requires just increasing the ref-count and is therefore cheaper than
cloning of `String` which requires a heap allocation and copying the
string contents.

This CL also changes the type of `ir::Identifier` because this is
the representation of `ir::Namespace::name`.

`Rc<str>` instead of `String` is possible because these strings are
never mutated.

PiperOrigin-RevId: 490605310
diff --git a/common/code_gen_utils.rs b/common/code_gen_utils.rs
index 78b151a..7087243 100644
--- a/common/code_gen_utils.rs
+++ b/common/code_gen_utils.rs
@@ -59,7 +59,7 @@
 // catch some error conditions early (e.g. an empty path component may trigger a
 // panic in `make_rs_ident`;  a reserved C++ keyword might trigger a late error
 // in `format_for_cc` / `format_cc_ident`).
-pub struct NamespaceQualifier(pub Vec<String>);
+pub struct NamespaceQualifier(pub Vec<Rc<str>>);
 
 impl NamespaceQualifier {
     pub fn format_for_rs(&self) -> TokenStream {
@@ -435,7 +435,7 @@
     }
 
     fn create_namespace_qualifier_for_tests(input: &[&str]) -> NamespaceQualifier {
-        NamespaceQualifier(input.into_iter().map(|s| s.to_string()).collect())
+        NamespaceQualifier(input.into_iter().map(|&s| s.into()).collect())
     }
 
     #[test]
diff --git a/rs_bindings_from_cc/ir.rs b/rs_bindings_from_cc/ir.rs
index d60ef34..51bf7af 100644
--- a/rs_bindings_from_cc/ir.rs
+++ b/rs_bindings_from_cc/ir.rs
@@ -162,7 +162,7 @@
 
 #[derive(PartialEq, Eq, Hash, Clone, Deserialize)]
 pub struct Identifier {
-    pub identifier: String,
+    pub identifier: Rc<str>,
 }
 
 impl fmt::Debug for Identifier {
@@ -254,7 +254,7 @@
 impl UnqualifiedIdentifier {
     pub fn identifier_as_str(&self) -> Option<&str> {
         match self {
-            UnqualifiedIdentifier::Identifier(identifier) => Some(identifier.identifier.as_str()),
+            UnqualifiedIdentifier::Identifier(identifier) => Some(identifier.identifier.as_ref()),
             _ => None,
         }
     }
@@ -878,7 +878,7 @@
 
     #[test]
     fn test_identifier_debug_print() {
-        assert_eq!(format!("{:?}", Identifier { identifier: "hello".to_string() }), "\"hello\"");
+        assert_eq!(format!("{:?}", Identifier { identifier: "hello".into() }), "\"hello\"");
     }
 
     #[test]
@@ -886,7 +886,7 @@
         assert_eq!(
             format!(
                 "{:?}",
-                UnqualifiedIdentifier::Identifier(Identifier { identifier: "hello".to_string() })
+                UnqualifiedIdentifier::Identifier(Identifier { identifier: "hello".into() })
             ),
             "\"hello\""
         );
diff --git a/rs_bindings_from_cc/ir_from_cc_test.rs b/rs_bindings_from_cc/ir_from_cc_test.rs
index 521ada9..55cf117 100644
--- a/rs_bindings_from_cc/ir_from_cc_test.rs
+++ b/rs_bindings_from_cc/ir_from_cc_test.rs
@@ -596,7 +596,7 @@
         .functions()
         .map(|f| {
             if let UnqualifiedIdentifier::Identifier(id) = &f.name {
-                (id.identifier.as_str(), f.doc_comment.as_deref())
+                (id.identifier.as_ref(), f.doc_comment.as_deref())
             } else {
                 panic!("No constructors/destructors expected in this test.")
             }
@@ -1138,7 +1138,7 @@
     let method_mangled_names = ir
         .functions()
         .filter_map(|f| match &f.name {
-            UnqualifiedIdentifier::Identifier(id) if id.identifier.as_str() == "MyMethod" => {
+            UnqualifiedIdentifier::Identifier(id) if id.identifier.as_ref() == "MyMethod" => {
                 Some(&f.mangled_name)
             }
             _ => None,
@@ -2382,7 +2382,7 @@
 
     assert_eq!(1, ir.namespaces().count());
     let ns = ir.namespaces().next().unwrap();
-    assert_eq!("MyNamespace", ns.name.identifier);
+    assert_eq!("MyNamespace", ns.name.identifier.as_ref());
     assert_eq!(1, ns.child_item_ids.len());
 
     let ns_id = ns.id;
@@ -2494,7 +2494,8 @@
     .unwrap();
     let foo_func =
         ir.functions().find(|f| f.name == UnqualifiedIdentifier::Identifier(ir_id("Foo"))).unwrap();
-    let param_names: Vec<_> = foo_func.params.iter().map(|p| &p.identifier.identifier).collect();
+    let param_names: Vec<_> =
+        foo_func.params.iter().map(|p| p.identifier.identifier.as_ref()).collect();
     assert_eq!(param_names, vec!["__this", "x", "y"]);
 }
 
diff --git a/rs_bindings_from_cc/ir_testing.rs b/rs_bindings_from_cc/ir_testing.rs
index e9b3ef5..8be4bce 100644
--- a/rs_bindings_from_cc/ir_testing.rs
+++ b/rs_bindings_from_cc/ir_testing.rs
@@ -82,7 +82,7 @@
 
 /// Creates an identifier
 pub fn ir_id(name: &str) -> Identifier {
-    Identifier { identifier: name.to_string() }
+    Identifier { identifier: name.into() }
 }
 
 /// Creates a simple `Item::Record` with a given name.
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 11153c4..544dde2 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -366,7 +366,7 @@
     let record: Option<&str> = ir.record_for_member_func(func)?.map(|r| &*r.cc_name);
 
     let func_name = match &func.name {
-        UnqualifiedIdentifier::Identifier(id) => id.identifier.clone(),
+        UnqualifiedIdentifier::Identifier(id) => id.identifier.to_string(),
         UnqualifiedIdentifier::Operator(op) => op.cc_name(),
         UnqualifiedIdentifier::Destructor => {
             format!("~{}", record.expect("destructor must be associated with a record"))
@@ -1213,7 +1213,7 @@
         *param = RsTypeKind::RvalueReference {
             referent: Rc::new(value),
             mutability: Mutability::Mut,
-            lifetime: new_lifetime_param(func_param.identifier.identifier.clone()),
+            lifetime: new_lifetime_param(func_param.identifier.identifier.to_string()),
         };
     }
 }
@@ -2857,7 +2857,7 @@
         };
         let idents = std::iter::once(crate_ident)
             .chain(ir.crate_root_path().into_iter().map(ToOwned::to_owned))
-            .chain(namespace_qualifiers.iter().cloned())
+            .chain(namespace_qualifiers.iter().map(|s| s.to_string()))
             .collect();
         CratePath { idents }
     }
@@ -6296,7 +6296,7 @@
             })
             .find(|f| {
                 matches!(&f.name, UnqualifiedIdentifier::Constructor)
-                    && f.params.get(1).map(|p| p.identifier.identifier == "i").unwrap_or_default()
+                    && f.params.get(1).map(|p| p.identifier.identifier.as_ref() == "i").unwrap_or_default()
             })
             .unwrap();
         {
@@ -7164,7 +7164,7 @@
         // const-ref + lifetimes in C++  ===>  shared-ref in Rust
         assert_eq!(foo_func.params.len(), 1);
         let foo_param = &foo_func.params[0];
-        assert_eq!(&foo_param.identifier.identifier, "foo_param");
+        assert_eq!(foo_param.identifier.identifier.as_ref(), "foo_param");
         let foo_type = db.rs_type_kind(foo_param.type_.rs_type.clone())?;
         assert!(foo_type.is_shared_ref_to(record));
         assert!(matches!(foo_type, RsTypeKind::Reference { mutability: Mutability::Const, .. }));
@@ -7172,7 +7172,7 @@
         // non-const-ref + lifetimes in C++  ===>  mutable-ref in Rust
         assert_eq!(bar_func.params.len(), 1);
         let bar_param = &bar_func.params[0];
-        assert_eq!(&bar_param.identifier.identifier, "bar_param");
+        assert_eq!(bar_param.identifier.identifier.as_ref(), "bar_param");
         let bar_type = db.rs_type_kind(bar_param.type_.rs_type.clone())?;
         assert!(!bar_type.is_shared_ref_to(record));
         assert!(matches!(bar_type, RsTypeKind::Reference { mutability: Mutability::Mut, .. }));
@@ -7193,7 +7193,7 @@
         // const-ref + *no* lifetimes in C++  ===>  const-pointer in Rust
         assert_eq!(foo_func.params.len(), 1);
         let foo_param = &foo_func.params[0];
-        assert_eq!(&foo_param.identifier.identifier, "foo_param");
+        assert_eq!(foo_param.identifier.identifier.as_ref(), "foo_param");
         let foo_type = db.rs_type_kind(foo_param.type_.rs_type.clone())?;
         assert!(!foo_type.is_shared_ref_to(record));
         assert!(matches!(foo_type, RsTypeKind::Pointer { mutability: Mutability::Const, .. }));