Replace 'static dyn Display with a formatter fn in printing type names
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 0a88a04..49b8927 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1276,7 +1276,9 @@
 
     quote_spanned! {end_span=>
         #unsafe_token impl #impl_generics ::cxx::private::UniquePtrTarget for #ident #ty_generics {
-            const __NAME: &'static dyn ::std::fmt::Display = &#name;
+            fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                f.write_str(#name)
+            }
             fn __null() -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_null]
@@ -1361,7 +1363,9 @@
 
     quote_spanned! {end_span=>
         #unsafe_token impl #impl_generics ::cxx::private::SharedPtrTarget for #ident #ty_generics {
-            const __NAME: &'static dyn ::std::fmt::Display = &#name;
+            fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                f.write_str(#name)
+            }
             unsafe fn __null(new: *mut ::std::ffi::c_void) {
                 extern "C" {
                     #[link_name = #link_null]
@@ -1418,7 +1422,9 @@
 
     quote_spanned! {end_span=>
         #unsafe_token impl #impl_generics ::cxx::private::WeakPtrTarget for #ident #ty_generics {
-            const __NAME: &'static dyn ::std::fmt::Display = &#name;
+            fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                f.write_str(#name)
+            }
             unsafe fn __null(new: *mut ::std::ffi::c_void) {
                 extern "C" {
                     #[link_name = #link_null]
@@ -1487,7 +1493,9 @@
 
     quote_spanned! {end_span=>
         #unsafe_token impl #impl_generics ::cxx::private::VectorElement for #elem #ty_generics {
-            const __NAME: &'static dyn ::std::fmt::Display = &#name;
+            fn __typename(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+                f.write_str(#name)
+            }
             fn __vector_size(v: &::cxx::CxxVector<Self>) -> usize {
                 extern "C" {
                     #[link_name = #link_size]
diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs
index d78ee47..c9c7d78 100644
--- a/src/cxx_vector.rs
+++ b/src/cxx_vector.rs
@@ -5,7 +5,7 @@
 use crate::kind::Trivial;
 use crate::string::CxxString;
 use core::ffi::c_void;
-use core::fmt::{self, Debug, Display};
+use core::fmt::{self, Debug};
 use core::iter::FusedIterator;
 use core::marker::{PhantomData, PhantomPinned};
 use core::mem;
@@ -263,32 +263,11 @@
     }
 }
 
-pub(crate) struct TypeName<T> {
-    element: PhantomData<T>,
-}
-
-impl<T> TypeName<T> {
-    pub const fn new() -> Self {
-        TypeName {
-            element: PhantomData,
-        }
-    }
-}
-
-impl<T> Display for TypeName<T>
-where
-    T: VectorElement,
-{
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        write!(formatter, "CxxVector<{}>", T::__NAME)
-    }
-}
-
 // Methods are private; not intended to be implemented outside of cxxbridge
 // codebase.
 #[doc(hidden)]
 pub unsafe trait VectorElement: Sized {
-    const __NAME: &'static dyn Display;
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
     fn __vector_size(v: &CxxVector<Self>) -> usize;
     unsafe fn __get_unchecked(v: *mut CxxVector<Self>, pos: usize) -> *mut Self;
     fn __unique_ptr_null() -> *mut c_void;
@@ -303,7 +282,9 @@
         const_assert_eq!(1, mem::align_of::<CxxVector<$ty>>());
 
         unsafe impl VectorElement for $ty {
-            const __NAME: &'static dyn Display = &$name;
+            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
+                f.write_str($name)
+            }
             fn __vector_size(v: &CxxVector<$ty>) -> usize {
                 extern "C" {
                     attr! {
diff --git a/src/fmt.rs b/src/fmt.rs
new file mode 100644
index 0000000..db14a7c
--- /dev/null
+++ b/src/fmt.rs
@@ -0,0 +1,16 @@
+use std::fmt::{self, Display};
+
+pub(crate) fn display(fmt: impl Fn(&mut fmt::Formatter) -> fmt::Result) -> impl Display {
+    DisplayInvoke(fmt)
+}
+
+struct DisplayInvoke<T>(T);
+
+impl<T> Display for DisplayInvoke<T>
+where
+    T: Fn(&mut fmt::Formatter) -> fmt::Result,
+{
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        (self.0)(formatter)
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 8282ea3..fb00d94 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -402,6 +402,7 @@
 
 mod exception;
 mod extern_type;
+mod fmt;
 mod function;
 mod opaque;
 mod result;
diff --git a/src/shared_ptr.rs b/src/shared_ptr.rs
index b3a1b1c..5893035 100644
--- a/src/shared_ptr.rs
+++ b/src/shared_ptr.rs
@@ -1,3 +1,4 @@
+use crate::fmt::display;
 use crate::kind::Trivial;
 use crate::string::CxxString;
 use crate::weak_ptr::{WeakPtr, WeakPtrTarget};
@@ -119,7 +120,10 @@
     fn deref(&self) -> &Self::Target {
         match self.as_ref() {
             Some(target) => target,
-            None => panic!("called deref on a null SharedPtr<{}>", T::__NAME),
+            None => panic!(
+                "called deref on a null SharedPtr<{}>",
+                display(T::__typename),
+            ),
         }
     }
 }
@@ -152,7 +156,7 @@
 // codebase.
 pub unsafe trait SharedPtrTarget {
     #[doc(hidden)]
-    const __NAME: &'static dyn Display;
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
     #[doc(hidden)]
     unsafe fn __null(new: *mut c_void);
     #[doc(hidden)]
@@ -177,7 +181,9 @@
 macro_rules! impl_shared_ptr_target {
     ($segment:expr, $name:expr, $ty:ty) => {
         unsafe impl SharedPtrTarget for $ty {
-            const __NAME: &'static dyn Display = &$name;
+            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
+                f.write_str($name)
+            }
             unsafe fn __null(new: *mut c_void) {
                 extern "C" {
                     attr! {
diff --git a/src/unique_ptr.rs b/src/unique_ptr.rs
index 0f9fa8f..1603881 100644
--- a/src/unique_ptr.rs
+++ b/src/unique_ptr.rs
@@ -1,6 +1,7 @@
+use crate::fmt::display;
 use crate::kind::Trivial;
 use crate::string::CxxString;
-use crate::vector::{self, CxxVector, VectorElement};
+use crate::vector::{CxxVector, VectorElement};
 use crate::ExternType;
 use core::ffi::c_void;
 use core::fmt::{self, Debug, Display};
@@ -77,7 +78,10 @@
     pub fn pin_mut(&mut self) -> Pin<&mut T> {
         match self.as_mut() {
             Some(target) => target,
-            None => panic!("called pin_mut on a null UniquePtr<{}>", T::__NAME),
+            None => panic!(
+                "called pin_mut on a null UniquePtr<{}>",
+                display(T::__typename),
+            ),
         }
     }
 
@@ -127,7 +131,10 @@
     fn deref(&self) -> &Self::Target {
         match self.as_ref() {
             Some(target) => target,
-            None => panic!("called deref on a null UniquePtr<{}>", T::__NAME),
+            None => panic!(
+                "called deref on a null UniquePtr<{}>",
+                display(T::__typename),
+            ),
         }
     }
 }
@@ -139,7 +146,10 @@
     fn deref_mut(&mut self) -> &mut Self::Target {
         match self.as_mut() {
             Some(target) => Pin::into_inner(target),
-            None => panic!("called deref_mut on a null UniquePtr<{}>", T::__NAME),
+            None => panic!(
+                "called deref_mut on a null UniquePtr<{}>",
+                display(T::__typename),
+            ),
         }
     }
 }
@@ -172,7 +182,7 @@
 // codebase.
 pub unsafe trait UniquePtrTarget {
     #[doc(hidden)]
-    const __NAME: &'static dyn Display;
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
     #[doc(hidden)]
     fn __null() -> *mut c_void;
     #[doc(hidden)]
@@ -209,7 +219,9 @@
 }
 
 unsafe impl UniquePtrTarget for CxxString {
-    const __NAME: &'static dyn Display = &"CxxString";
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
+        f.write_str("CxxString")
+    }
     fn __null() -> *mut c_void {
         let mut repr = ptr::null_mut::<c_void>();
         unsafe {
@@ -237,7 +249,9 @@
 where
     T: VectorElement + 'static,
 {
-    const __NAME: &'static dyn Display = &vector::TypeName::<T>::new();
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "CxxVector<{}>", display(T::__typename))
+    }
     fn __null() -> *mut c_void {
         T::__unique_ptr_null()
     }
diff --git a/src/weak_ptr.rs b/src/weak_ptr.rs
index 7fc4c78..ba74461 100644
--- a/src/weak_ptr.rs
+++ b/src/weak_ptr.rs
@@ -1,7 +1,7 @@
 use crate::shared_ptr::{SharedPtr, SharedPtrTarget};
 use crate::string::CxxString;
 use core::ffi::c_void;
-use core::fmt::{self, Debug, Display};
+use core::fmt::{self, Debug};
 use core::marker::PhantomData;
 use core::mem::MaybeUninit;
 
@@ -95,7 +95,7 @@
 // codebase.
 pub unsafe trait WeakPtrTarget {
     #[doc(hidden)]
-    const __NAME: &'static dyn Display;
+    fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
     #[doc(hidden)]
     unsafe fn __null(new: *mut c_void);
     #[doc(hidden)]
@@ -111,7 +111,9 @@
 macro_rules! impl_weak_ptr_target {
     ($segment:expr, $name:expr, $ty:ty) => {
         unsafe impl WeakPtrTarget for $ty {
-            const __NAME: &'static dyn Display = &$name;
+            fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
+                f.write_str($name)
+            }
             unsafe fn __null(new: *mut c_void) {
                 extern "C" {
                     attr! {