Switch to rustc-demangle to demangle rust symbols
diff --git a/.gitmodules b/.gitmodules
index eb37693..0587707 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -19,3 +19,6 @@
 [submodule "third_party/flatbuffers"]
 	path = third_party/flatbuffers
 	url = https://github.com/google/flatbuffers.git
+[submodule "third_party/rustc-demangle"]
+	path = third_party/rustc-demangle
+	url = https://github.com/alexcrichton/rustc-demangle.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23dccfa..3a785b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,6 +91,7 @@
 include_directories(src)
 include_directories(third_party/abseil-cpp)
 include_directories(third_party/flatbuffers/include)
+include_directories(third_party/rustc-demangle/crates/capi/include)
 include_directories("${CMAKE_CURRENT_BINARY_DIR}/src")
 
 # Baseline build flags.
@@ -205,9 +206,9 @@
   else(${CAPSTONE_FOUND})
     set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} capstone-static)
   endif(${CAPSTONE_FOUND})
-  set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rustfilt/target/release/librustfilt.a" dl)
+  set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rustc-demangle/target/release/librustc_demangle.a" dl)
 else(UNIX)
-    set(LIBBLOATY_LIBS libbloaty libprotoc re2 capstone-static "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rustfilt/target/release/librustfilt.a" dl)
+    set(LIBBLOATY_LIBS libbloaty libprotoc re2 capstone-static "${CMAKE_CURRENT_SOURCE_DIR}/third_party/rustc-demangle/target/release/librustc_demangle.a" dl)
 endif(UNIX)
 
 if(UNIX)
diff --git a/build_all.sh b/build_all.sh
index e7dc51f..4f26cd2 100755
--- a/build_all.sh
+++ b/build_all.sh
@@ -4,8 +4,8 @@
 
 pushd "${0%/*}"
 
-pushd third_party/rustfilt
-cargo build --workspace --release
+pushd third_party/rustc-demangle
+cargo build -p rustc-demangle-capi --release
 popd
 
 rm -rf build
diff --git a/src/bloaty.cc b/src/bloaty.cc
index 369e4ad..cb7603c 100644
--- a/src/bloaty.cc
+++ b/src/bloaty.cc
@@ -52,7 +52,7 @@
 #include "bloaty.pb.h"
 #include "demangle.h"
 #include "report_generated.h"
-#include "rust_demangle.h"
+#include "rustc_demangle.h"
 
 using absl::string_view;
 
@@ -236,6 +236,22 @@
   return LineReader(pipe, true);
 }
 
+namespace {
+
+std::string DemangleRustSymbol(std::string_view mangled) {
+  constexpr size_t kBufferSize = 8192;
+  std::unique_ptr<std::array<char, kBufferSize>> buffer =
+      std::make_unique<std::array<char, kBufferSize>>();
+  int result = rustc_demangle(mangled.data(), buffer->data(), kBufferSize);
+  if (result == 1) {
+    return std::string(buffer->data());
+  } else {
+    return "";
+  }
+}
+
+}  // namespace
+
 extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n,
                                 int* status);
 
@@ -252,28 +268,28 @@
 
   if (absl::StartsWith(demangle_from, "_R")) {
     // Demangle Rust symbols
-    char* demangled = demangle_rust_symbol(demangle_from.data());
-    std::string ret(demangled);
-    recycle_demangle_result(demangled);
-    return ret;
+    std::string ret = DemangleRustSymbol(demangle_from);
+    if (!ret.empty()) {
+      return ret;
+    }
   }
 
   if (absl::StartsWith(demangle_from, "switch.table._R")) {
     // Demangle Rust symbols for switch tables
     demangle_from.remove_prefix(13);
-    char* demangled = demangle_rust_symbol(demangle_from.data());
-    std::string ret(demangled);
-    recycle_demangle_result(demangled);
-    return "switch.table." + ret;
+    std::string ret = DemangleRustSymbol(demangle_from);
+    if (!ret.empty()) {
+      return "switch.table." + ret;
+    }
   }
 
   if (absl::StartsWith(demangle_from, ".Lswitch.table._R")) {
-    // Demangle Rust symbols for switch tables
+    // Demangle Rust symbols for switch tables, with ".L" prefix.
     demangle_from.remove_prefix(15);
-    char* demangled = demangle_rust_symbol(demangle_from.data());
-    std::string ret(demangled);
-    recycle_demangle_result(demangled);
-    return "switch.table." + ret;
+    std::string ret = DemangleRustSymbol(demangle_from);
+    if (!ret.empty()) {
+      return "switch.table." + ret;
+    }
   }
 
   if (source == DataSource::kShortSymbols) {
@@ -282,6 +298,7 @@
       return std::string(demangled);
     } else {
       // TODO(yifeit): Certain symbols have dots (".") in them. Those are not allowed.
+      // Find and remove the last "." and anything after.
       auto pos = demangle_from.find(".");
       if (pos != absl::string_view::npos) {
         demangle_from.remove_suffix(demangle_from.length() - pos);
@@ -301,6 +318,7 @@
       return ret;
     } else {
       // TODO(yifeit): Certain symbols have dots (".") in them. Those are not allowed.
+      // Find and remove the last "." and anything after.
       auto pos = demangle_from.find(".");
       if (pos != absl::string_view::npos) {
         demangle_from.remove_suffix(demangle_from.length() - pos);
diff --git a/src/rust_demangle.h b/src/rust_demangle.h
deleted file mode 100644
index ee695f9..0000000
--- a/src/rust_demangle.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef BASE_RUST_DEMANGLE_H_
-#define BASE_RUST_DEMANGLE_H_
-
-extern "C" {
-
-char* demangle_rust_symbol(const char* mangled);
-void recycle_demangle_result(char* demangled);
-
-};
-
-#endif  // BASE_RUST_DEMANGLE_H_
diff --git a/third_party/rustc-demangle b/third_party/rustc-demangle
new file mode 160000
index 0000000..c4e3ab0
--- /dev/null
+++ b/third_party/rustc-demangle
@@ -0,0 +1 @@
+Subproject commit c4e3ab004edda9fbe5e2d8149d2b62c10668d10b