Support for C++ namespaces named after reserved Rust keywords.

This mostly requires bifurcating `generate_namespace_qualifier` into a
C++ and a Rust-oriented version (one using `make_rs_ident` and one using
`format_cc_ident`).

PiperOrigin-RevId: 471520348
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 74710fb..0199424 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -1548,8 +1548,7 @@
     Ok(!ty_implements_copy)
 }
 
-/// Returns the namespace qualifier for the given item.
-fn generate_namespace_qualifier(item_id: ItemId, ir: &IR) -> Result<impl Iterator<Item = Ident>> {
+fn get_namespaces(item_id: ItemId, ir: &IR) -> Result<impl Iterator<Item = &Namespace>> {
     let mut namespaces = vec![];
     let item: &Item = ir.find_decl(item_id)?;
     let mut enclosing_namespace_id = item.enclosing_namespace_id();
@@ -1557,7 +1556,7 @@
         let namespace_item = ir.find_decl(parent_id)?;
         match namespace_item {
             Item::Namespace(ns) => {
-                namespaces.push(make_rs_ident(&ns.name.identifier));
+                namespaces.push(ns.as_ref());
                 enclosing_namespace_id = ns.enclosing_namespace_id;
             }
             _ => {
@@ -1568,6 +1567,20 @@
     Ok(namespaces.into_iter().rev())
 }
 
+/// Returns the Rust namespace qualifier for the given item.
+fn format_rs_namespace_qualifier(item_id: ItemId, ir: &IR) -> Result<TokenStream> {
+    let namespace_rs_idents =
+        get_namespaces(item_id, ir)?.map(|ns| make_rs_ident(&ns.name.identifier));
+    Ok(quote! { #(#namespace_rs_idents::)* })
+}
+
+/// Returns the C++ namespace qualifier for the given item.
+fn format_cc_namespace_qualifier(item_id: ItemId, ir: &IR) -> Result<TokenStream> {
+    let namespace_cc_idents =
+        get_namespaces(item_id, ir)?.map(|ns| format_cc_ident(&ns.name.identifier));
+    Ok(quote! { #(#namespace_cc_idents::)* })
+}
+
 /// Generates Rust source code for a given incomplete record declaration.
 fn generate_incomplete_record(incomplete_record: &IncompleteRecord) -> Result<TokenStream> {
     let ident = make_rs_ident(&incomplete_record.rs_name);
@@ -1613,9 +1626,9 @@
 fn generate_record(db: &Database, record: &Rc<Record>) -> Result<GeneratedItem> {
     let ir = db.ir();
     let ident = make_rs_ident(&record.rs_name);
-    let namespace_qualifier = generate_namespace_qualifier(record.id, &ir)?;
+    let namespace_qualifier = format_rs_namespace_qualifier(record.id, &ir)?;
     let qualified_ident = {
-        quote! { crate:: #(#namespace_qualifier::)* #ident }
+        quote! { crate:: #namespace_qualifier #ident }
     };
     let doc_comment = generate_doc_comment(&record.doc_comment);
 
@@ -2497,13 +2510,13 @@
         /// The imported crate this comes from, or None if the current crate.
         crate_ident: Option<Ident>,
         /// The namespace qualifier for this record.
-        namespace_qualifier: Rc<[Ident]>,
+        namespace_qualifier: RcEq<TokenStream>,
     },
     /// A complete record type.
     Record {
         record: Rc<Record>,
         /// The namespace qualifier for this record.
-        namespace_qualifier: Rc<[Ident]>,
+        namespace_qualifier: RcEq<TokenStream>,
         /// The imported crate this comes from, or None if the current crate.
         crate_ident: Option<Ident>,
     },
@@ -2511,7 +2524,7 @@
         type_alias: Rc<TypeAlias>,
         underlying_type: Rc<RsTypeKind>,
         /// The namespace qualifier for this alias.
-        namespace_qualifier: Rc<[Ident]>,
+        namespace_qualifier: RcEq<TokenStream>,
         /// The imported crate this comes from, or None if the current crate.
         crate_ident: Option<Ident>,
     },
@@ -2524,7 +2537,7 @@
 
 impl RsTypeKind {
     pub fn new_record(record: Rc<Record>, ir: &IR) -> Result<Self> {
-        let namespace_qualifier = generate_namespace_qualifier(record.id, ir)?.collect();
+        let namespace_qualifier = RcEq::new(format_rs_namespace_qualifier(record.id, ir)?);
         let crate_ident = rs_imported_crate_name(&record.owning_target, ir);
         Ok(RsTypeKind::Record { record, namespace_qualifier, crate_ident })
     }
@@ -2759,37 +2772,34 @@
                 crate_ident,
             } => {
                 let record_ident = make_rs_ident(&incomplete_record.rs_name);
-                let namespace_idents = namespace_qualifier.iter();
                 match crate_ident {
                     Some(ci) => {
-                        quote! { #ci #(#namespace_idents::)*  #record_ident }
+                        quote! { #ci #namespace_qualifier #record_ident }
                     }
                     None => {
-                        quote! { crate:: #(#namespace_idents::)*  #record_ident }
+                        quote! { crate:: #namespace_qualifier #record_ident }
                     }
                 }
             }
             RsTypeKind::Record { record, namespace_qualifier, crate_ident } => {
                 let ident = make_rs_ident(&record.rs_name);
-                let namespace_idents = namespace_qualifier.iter();
                 match crate_ident {
                     Some(ci) => {
-                        quote! { #ci:: #(#namespace_idents::)*  #ident }
+                        quote! { #ci:: #namespace_qualifier #ident }
                     }
                     None => {
-                        quote! { crate:: #(#namespace_idents::)*  #ident }
+                        quote! { crate:: #namespace_qualifier #ident }
                     }
                 }
             }
             RsTypeKind::TypeAlias { type_alias, namespace_qualifier, crate_ident, .. } => {
                 let ident = make_rs_ident(&type_alias.identifier.identifier);
-                let namespace_idents = namespace_qualifier.iter();
                 match crate_ident {
                     Some(ci) => {
-                        quote! { #ci:: #(#namespace_idents::)*  #ident }
+                        quote! { #ci:: #namespace_qualifier #ident }
                     }
                     None => {
-                        quote! { crate:: #(#namespace_idents::)*  #ident }
+                        quote! { crate:: #namespace_qualifier #ident }
                     }
                 }
             }
@@ -2882,15 +2892,13 @@
             match ir.item_for_type(&ty)? {
                 Item::IncompleteRecord(incomplete_record) => RsTypeKind::IncompleteRecord {
                     incomplete_record: incomplete_record.clone(),
-                    namespace_qualifier: generate_namespace_qualifier(incomplete_record.id, &ir)?
-                        .collect(),
+                    namespace_qualifier: RcEq::new(format_rs_namespace_qualifier(incomplete_record.id, &ir)?),
                     crate_ident: rs_imported_crate_name(&incomplete_record.owning_target, &ir),
                 },
                 Item::Record(record) => RsTypeKind::new_record(record.clone(), &ir)?,
                 Item::TypeAlias(type_alias) => RsTypeKind::TypeAlias {
                     type_alias: type_alias.clone(),
-                    namespace_qualifier: generate_namespace_qualifier(type_alias.id, &ir)?
-                        .collect(),
+                    namespace_qualifier: RcEq::new(format_rs_namespace_qualifier(type_alias.id, &ir)?),
                     crate_ident: rs_imported_crate_name(&type_alias.owning_target, &ir),
                     underlying_type: Rc::new(
                         db.rs_type_kind(type_alias.underlying_type.rs_type.clone())?,
@@ -2954,20 +2962,20 @@
     Ok(match item {
         Item::IncompleteRecord(incomplete_record) => {
             let ident = format_cc_ident(&incomplete_record.cc_name);
-            let namespace_qualifier = generate_namespace_qualifier(incomplete_record.id, ir)?;
+            let namespace_qualifier = format_cc_namespace_qualifier(incomplete_record.id, ir)?;
             let tag_kind = incomplete_record.record_type;
-            quote! { #tag_kind #(#namespace_qualifier::)*  #ident }
+            quote! { #tag_kind #namespace_qualifier #ident }
         }
         Item::Record(record) => {
             let ident = format_cc_ident(&record.cc_name);
-            let namespace_qualifier = generate_namespace_qualifier(record.id, ir)?;
+            let namespace_qualifier = format_cc_namespace_qualifier(record.id, ir)?;
             let tag_kind = cc_tag_kind(record);
-            quote! { #tag_kind #(#namespace_qualifier::)*  #ident }
+            quote! { #tag_kind #namespace_qualifier #ident }
         }
         Item::TypeAlias(type_alias) => {
             let ident = format_cc_ident(&type_alias.identifier.identifier);
-            let namespace_qualifier = generate_namespace_qualifier(type_alias.id, ir)?;
-            quote! { #(#namespace_qualifier::)* #ident }
+            let namespace_qualifier = format_cc_namespace_qualifier(type_alias.id, ir)?;
+            quote! { #namespace_qualifier #ident }
         }
         _ => bail!("Item does not define a type: {:?}", item),
     })
@@ -3057,8 +3065,7 @@
         return Ok(quote! {});
     }
     let record_ident = format_cc_ident(&record.cc_name);
-    let namespace_qualifier = generate_namespace_qualifier(record.id, ir)?;
-    let namespace_qualifier = quote! { #(#namespace_qualifier::)* };
+    let namespace_qualifier = format_cc_namespace_qualifier(record.id, ir)?;
     let cc_size = Literal::usize_unsuffixed(record.original_cc_size);
     let alignment = Literal::usize_unsuffixed(record.alignment);
     let tag_kind = cc_tag_kind(record);
@@ -3224,13 +3231,13 @@
                         } else {
                             let record: &Rc<Record> = ir.find_decl(meta.record_id)?;
                             let record_ident = format_cc_ident(&record.cc_name);
-                            let namespace_qualifier = generate_namespace_qualifier(record.id, &ir)?;
-                            quote! { #(#namespace_qualifier::)* #record_ident :: #fn_ident }
+                            let namespace_qualifier = format_cc_namespace_qualifier(record.id, &ir)?;
+                            quote! { #namespace_qualifier #record_ident :: #fn_ident }
                         }
                     }
                     None => {
-                        let namespace_qualifier = generate_namespace_qualifier(func.id, &ir)?;
-                        quote! { #(#namespace_qualifier::)* #fn_ident }
+                        let namespace_qualifier = format_cc_namespace_qualifier(func.id, &ir)?;
+                        quote! { #namespace_qualifier #fn_ident }
                     }
                 }
             }