Move CppName's namespace into Pair
diff --git a/syntax/ident.rs b/syntax/ident.rs
index 03c4380..bb2fe46 100644
--- a/syntax/ident.rs
+++ b/syntax/ident.rs
@@ -1,5 +1,5 @@
 use crate::syntax::check::Check;
-use crate::syntax::{error, Api, CppName};
+use crate::syntax::{error, Api, Pair};
 use proc_macro2::Ident;
 
 fn check(cx: &mut Check, ident: &Ident) {
@@ -12,11 +12,11 @@
     }
 }
 
-fn check_ident(cx: &mut Check, ident: &CppName) {
-    for segment in &ident.namespace {
+fn check_ident(cx: &mut Check, name: &Pair) {
+    for segment in &name.namespace {
         check(cx, segment);
     }
-    check(cx, &ident.ident);
+    check(cx, &name.cxx);
 }
 
 pub(crate) fn check_all(cx: &mut Check, apis: &[Api]) {
@@ -24,19 +24,19 @@
         match api {
             Api::Include(_) | Api::Impl(_) => {}
             Api::Struct(strct) => {
-                check_ident(cx, &strct.ident.cxx);
+                check_ident(cx, &strct.ident);
                 for field in &strct.fields {
                     check(cx, &field.ident);
                 }
             }
             Api::Enum(enm) => {
-                check_ident(cx, &enm.ident.cxx);
+                check_ident(cx, &enm.ident);
                 for variant in &enm.variants {
                     check(cx, &variant.ident);
                 }
             }
             Api::CxxType(ety) | Api::RustType(ety) => {
-                check_ident(cx, &ety.ident.cxx);
+                check_ident(cx, &ety.ident);
             }
             Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                 check(cx, &efn.ident.rust);
@@ -45,7 +45,7 @@
                 }
             }
             Api::TypeAlias(alias) => {
-                check_ident(cx, &alias.ident.cxx);
+                check_ident(cx, &alias.ident);
             }
         }
     }
diff --git a/syntax/mangle.rs b/syntax/mangle.rs
index d1f3adc..55ffca5 100644
--- a/syntax/mangle.rs
+++ b/syntax/mangle.rs
@@ -15,13 +15,13 @@
         Some(receiver) => {
             let receiver_ident = types.resolve(&receiver.ty);
             join!(
-                efn.ident.cxx.namespace,
+                efn.ident.namespace,
                 CXXBRIDGE,
-                receiver_ident.ident,
+                receiver_ident.cxx,
                 efn.ident.rust
             )
         }
-        None => join!(efn.ident.cxx.namespace, CXXBRIDGE, efn.ident.rust),
+        None => join!(efn.ident.namespace, CXXBRIDGE, efn.ident.rust),
     }
 }
 
diff --git a/syntax/mod.rs b/syntax/mod.rs
index b12d72b..6684b6a 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -188,17 +188,9 @@
 // qualified C++ name.
 #[derive(Clone)]
 pub struct Pair {
-    pub cxx: CppName,
-    pub rust: Ident,
-}
-
-// A C++ identifier in a particular namespace. It is intentional that this does
-// not impl Display, because we want to force users actively to decide whether
-// to output it as a qualified name or as an unqualfied name.
-#[derive(Clone)]
-pub struct CppName {
     pub namespace: Namespace,
-    pub ident: Ident,
+    pub cxx: Ident,
+    pub rust: Ident,
 }
 
 // Wrapper for a type which needs to be resolved before it can be printed in
diff --git a/syntax/names.rs b/syntax/names.rs
index ee010a9..25ae9f4 100644
--- a/syntax/names.rs
+++ b/syntax/names.rs
@@ -1,29 +1,51 @@
-use crate::syntax::{CppName, Namespace, Pair, ResolvableName, Symbol, Types};
+use crate::syntax::{Namespace, Pair, ResolvableName, Symbol, Types};
 use proc_macro2::{Ident, Span};
+use std::iter;
 use syn::Token;
 
 impl Pair {
-    /// Use this constructor when the item can't have a different
-    /// name in Rust and C++.
+    // Use this constructor when the item can't have a different name in Rust
+    // and C++.
     pub fn new(namespace: Namespace, ident: Ident) -> Self {
         Self {
-            rust: ident.clone(),
-            cxx: CppName::new(namespace, ident),
+            namespace,
+            cxx: ident.clone(),
+            rust: ident,
         }
     }
 
-    /// Use this constructor when attributes such as #[rust_name]
-    /// can be used to potentially give a different name in Rust vs C++.
+    // Use this constructor when attributes such as #[rust_name] can be used to
+    // potentially give a different name in Rust vs C++.
     pub fn new_from_differing_names(
         namespace: Namespace,
         cxx_ident: Ident,
         rust_ident: Ident,
     ) -> Self {
         Self {
+            namespace,
+            cxx: cxx_ident,
             rust: rust_ident,
-            cxx: CppName::new(namespace, cxx_ident),
         }
     }
+
+    pub fn to_symbol(&self) -> Symbol {
+        Symbol::from_idents(self.iter_all_segments())
+    }
+
+    pub fn to_fully_qualified(&self) -> String {
+        format!("::{}", self.join("::"))
+    }
+
+    fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
+        self.namespace.iter().chain(iter::once(&self.cxx))
+    }
+
+    fn join(&self, sep: &str) -> String {
+        self.iter_all_segments()
+            .map(|s| s.to_string())
+            .collect::<Vec<_>>()
+            .join(sep)
+    }
 }
 
 impl ResolvableName {
@@ -49,28 +71,3 @@
         types.resolve(self).to_symbol()
     }
 }
-
-impl CppName {
-    pub fn new(namespace: Namespace, ident: Ident) -> Self {
-        Self { namespace, ident }
-    }
-
-    fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
-        self.namespace.iter().chain(std::iter::once(&self.ident))
-    }
-
-    fn join(&self, sep: &str) -> String {
-        self.iter_all_segments()
-            .map(|s| s.to_string())
-            .collect::<Vec<_>>()
-            .join(sep)
-    }
-
-    pub fn to_symbol(&self) -> Symbol {
-        Symbol::from_idents(self.iter_all_segments())
-    }
-
-    pub fn to_fully_qualified(&self) -> String {
-        format!("::{}", self.join("::"))
-    }
-}
diff --git a/syntax/symbol.rs b/syntax/symbol.rs
index c849a62..253f57d 100644
--- a/syntax/symbol.rs
+++ b/syntax/symbol.rs
@@ -1,5 +1,5 @@
 use crate::syntax::namespace::Namespace;
-use crate::syntax::CppName;
+use crate::syntax::Pair;
 use proc_macro2::{Ident, TokenStream};
 use quote::ToTokens;
 use std::fmt::{self, Display, Write};
@@ -79,10 +79,10 @@
     }
 }
 
-impl Segment for CppName {
+impl Segment for Pair {
     fn write(&self, symbol: &mut Symbol) {
         self.namespace.write(symbol);
-        self.ident.write(symbol);
+        self.cxx.write(symbol);
     }
 }
 
diff --git a/syntax/types.rs b/syntax/types.rs
index 178da3e..d9d6361 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -2,8 +2,7 @@
 use crate::syntax::report::Errors;
 use crate::syntax::set::OrderedSet as Set;
 use crate::syntax::{
-    Api, CppName, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Struct, Type,
-    TypeAlias,
+    Api, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Struct, Type, TypeAlias,
 };
 use proc_macro2::Ident;
 use quote::ToTokens;
@@ -19,7 +18,7 @@
     pub untrusted: Map<&'a Ident, &'a ExternType>,
     pub required_trivial: Map<&'a Ident, TrivialReason<'a>>,
     pub explicit_impls: Set<&'a Impl>,
-    pub resolutions: Map<&'a Ident, &'a CppName>,
+    pub resolutions: Map<&'a Ident, &'a Pair>,
 }
 
 impl<'a> Types<'a> {
@@ -56,7 +55,7 @@
         }
 
         let mut add_resolution = |pair: &'a Pair| {
-            resolutions.insert(&pair.rust, &pair.cxx);
+            resolutions.insert(&pair.rust, pair);
         };
 
         let mut type_names = UnorderedSet::new();
@@ -228,7 +227,7 @@
         false
     }
 
-    pub fn resolve(&self, ident: &ResolvableName) -> &CppName {
+    pub fn resolve(&self, ident: &ResolvableName) -> &Pair {
         self.resolutions
             .get(&ident.rust)
             .expect("Unable to resolve type")