diff --git a/src/lib.rs b/src/lib.rs
index 2281b52..41bc796 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,6 +31,7 @@
 extern crate std;
 
 mod legacy;
+mod v0;
 
 use core::fmt;
 
@@ -43,6 +44,7 @@
 
 enum DemangleStyle<'a> {
     Legacy(legacy::Demangle<'a>),
+    V0(v0::Demangle<'a>),
 }
 
 /// De-mangles a Rust symbol into a more readable version
@@ -93,7 +95,10 @@
 
     let style = match legacy::demangle(s) {
         Ok(d) => Some(DemangleStyle::Legacy(d)),
-        Err(()) => None,
+        Err(()) => match v0::demangle(s) {
+            Ok(d) => Some(DemangleStyle::V0(d)),
+            Err(v0::Invalid) => None,
+        },
     };
     Demangle {
         style: style,
@@ -174,6 +179,9 @@
             Some(DemangleStyle::Legacy(ref d)) => {
                 try!(fmt::Display::fmt(d, f))
             }
+            Some(DemangleStyle::V0(ref d)) => {
+                try!(fmt::Display::fmt(d, f))
+            }
         }
         f.write_str(self.suffix)
     }
diff --git a/src/v0.rs b/src/v0.rs
new file mode 100644
index 0000000..791742c
--- /dev/null
+++ b/src/v0.rs
@@ -0,0 +1,1040 @@
+use core::char;
+use core::fmt;
+use core::fmt::Display;
+
+/// Representation of a demangled symbol name.
+pub struct Demangle<'a> {
+    inner: &'a str,
+}
+
+/// De-mangles a Rust symbol into a more readable version
+///
+/// This function will take a **mangled** symbol and return a value. When printed,
+/// the de-mangled version will be written. If the symbol does not look like
+/// a mangled symbol, the original value will be written instead.
+pub fn demangle(s: &str) -> Result<Demangle, Invalid> {
+    // First validate the symbol. If it doesn't look like anything we're
+    // expecting, we just print it literally. Note that we must handle non-Rust
+    // symbols because we could have any function in the backtrace.
+    let inner;
+    if s.len() > 2 && s.starts_with("_R") {
+        inner = &s[2..];
+    } else if s.len() > 1 && s.starts_with("R") {
+        // On Windows, dbghelp strips leading underscores, so we accept "R..."
+        // form too.
+        inner = &s[1..];
+    } else if s.len() > 3 && s.starts_with("__R") {
+        // On OSX, symbols are prefixed with an extra _
+        inner = &s[3..];
+    } else {
+        return Err(Invalid);
+    }
+
+    // Paths always start with uppercase characters.
+    match inner.as_bytes()[0] {
+        b'A'...b'Z' => {}
+        _ => return Err(Invalid),
+    }
+
+    // only work with ascii text
+    if inner.bytes().any(|c| c & 0x80 != 0) {
+        return Err(Invalid);
+    }
+
+    // Verify that the symbol is indeed a valid path.
+    let mut parser = Parser {
+        sym: inner,
+        next: 0,
+    };
+    try!(parser.skip_path());
+    if parser.next < parser.sym.len() {
+        // Instantiating crate.
+        try!(parser.skip_path());
+    }
+    if parser.next != parser.sym.len() {
+        return Err(Invalid);
+    }
+
+    Ok(Demangle {
+        inner: inner,
+    })
+}
+
+impl<'s> Display for Demangle<'s> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut printer = Printer {
+            parser: Ok(Parser {
+                sym: self.inner,
+                next: 0,
+            }),
+            out: f,
+            bound_lifetime_depth: 0,
+        };
+        printer.print_path(true)
+    }
+}
+
+#[derive(PartialEq, Eq)]
+pub struct Invalid;
+
+struct Ident<'s> {
+    /// ASCII part of the identifier.
+    ascii: &'s str,
+    /// Punycode insertion codes for Unicode codepoints, if any.
+    punycode: &'s str,
+}
+
+const SMALL_PUNYCODE_LEN: usize = 128;
+
+impl<'s> Ident<'s> {
+    /// Attempt to decode punycode on the stack (allocation-free),
+    /// and pass the char slice to the closure, if successful.
+    /// This supports up to `SMALL_PUNYCODE_LEN` characters.
+    fn try_small_punycode_decode<F: FnOnce(&[char]) -> R, R>(
+        &self,
+        f: F,
+    ) -> Option<R> {
+        let mut out = ['\0'; SMALL_PUNYCODE_LEN];
+        let mut out_len = 0;
+        let r = self.punycode_decode(|i, c| {
+            // Check there's space left for another character.
+            try!(out.get(out_len).ok_or(()));
+
+            // Move the characters after the insert position.
+            let mut j = out_len;
+            out_len += 1;
+
+            while j > i {
+                out[j] = out[j - 1];
+                j -= 1;
+            }
+
+            // Insert the new character.
+            out[i] = c;
+
+            Ok(())
+        });
+        if r.is_ok() {
+            Some(f(&out[..out_len]))
+        } else {
+            None
+        }
+    }
+
+    /// Decode punycode as insertion positions and characters
+    /// and pass them to the closure, which can return `Err(())`
+    /// to stop the decoding process.
+    fn punycode_decode<F: FnMut(usize, char) -> Result<(), ()>>(
+        &self,
+        mut insert: F,
+    ) -> Result<(), ()> {
+        let mut punycode_bytes = self.punycode.bytes().peekable();
+        if punycode_bytes.peek().is_none() {
+            return Err(());
+        }
+
+        let mut len = 0;
+
+        // Populate initial output from ASCII fragment.
+        for c in self.ascii.chars() {
+            try!(insert(len, c));
+            len += 1;
+        }
+
+        // Punycode parameters and initial state.
+        let base = 36;
+        let t_min = 1;
+        let t_max = 26;
+        let skew = 38;
+        let mut damp = 700;
+        let mut bias = 72;
+        let mut i: usize = 0;
+        let mut n: usize = 0x80;
+
+        loop {
+            // Read one delta value.
+            let mut delta: usize = 0;
+            let mut w = 1;
+            let mut k: usize = 0;
+            loop {
+                use core::cmp::{min, max};
+
+                k += base;
+                let t = min(max(k.saturating_sub(bias), t_min), t_max);
+
+                let d = match punycode_bytes.next() {
+                    Some(d @ b'a'...b'z') => d - b'a',
+                    Some(d @ b'A'...b'J') => 26 + (d - b'A'),
+                    _ => return Err(()),
+                };
+                let d = d as usize;
+                delta = try!(delta.checked_add(
+                    try!(d.checked_mul(w).ok_or(()))
+                ).ok_or(()));
+                if d < t {
+                    break;
+                }
+                w = try!(w.checked_mul(base - t).ok_or(()));
+            }
+
+            // Compute the new insert position and character.
+            len += 1;
+            i = try!(i.checked_add(delta).ok_or(()));
+            n = try!(n.checked_add(i / len).ok_or(()));
+            i %= len;
+
+            let n_u32 = n as u32;
+            let c = if n_u32 as usize == n {
+                try!(char::from_u32(n_u32).ok_or(()))
+            } else {
+                return Err(());
+            };
+
+            // Insert the new character and increment the insert position.
+            try!(insert(i, c));
+            i += 1;
+
+            // If there are no more deltas, decoding is complete.
+            if punycode_bytes.peek().is_none() {
+                return Ok(());
+            }
+
+            // Perform bias adaptation.
+            delta /= damp;
+            damp = 2;
+
+            delta += delta / len;
+            let mut k = 0;
+            while delta > ((base - t_min) * t_max) / 2 {
+                delta /= base - t_min;
+                k += base;
+            }
+            bias = k + ((base - t_min + 1) * delta) / (delta + skew);
+        }
+    }
+}
+
+impl<'s> Display for Ident<'s> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.try_small_punycode_decode(|chars| {
+            for &c in chars {
+                try!(c.fmt(f));
+            }
+            Ok(())
+        }).unwrap_or_else(|| {
+            if !self.punycode.is_empty() {
+                try!(f.write_str("punycode{"));
+
+                // Reconstruct a standard Punycode encoding,
+                // by using `-` as the separator and replacing
+                // [A-J] with [0-9] (in the base36 codes).
+                if !self.ascii.is_empty() {
+                    try!(f.write_str(self.ascii));
+                    try!(f.write_str("-"));
+                }
+                for mut b in self.punycode.bytes() {
+                    if let b'A'...b'J' = b {
+                        b = b - b'A' + b'0';
+                    }
+                    try!((b as char).fmt(f));
+                }
+
+                f.write_str("}")
+            } else {
+                f.write_str(self.ascii)
+            }
+        })
+    }
+}
+
+fn basic_type(tag: u8) -> Option<&'static str> {
+    Some(match tag {
+        b'b' => "bool",
+        b'c' => "char",
+        b'e' => "str",
+        b'u' => "()",
+        b'a' => "i8",
+        b's' => "i16",
+        b'l' => "i32",
+        b'x' => "i64",
+        b'n' => "i128",
+        b'i' => "isize",
+        b'h' => "u8",
+        b't' => "u16",
+        b'm' => "u32",
+        b'y' => "u64",
+        b'o' => "u128",
+        b'j' => "usize",
+        b'f' => "f32",
+        b'd' => "f64",
+        b'z' => "!",
+        b'p' => "_",
+        b'v' => "...",
+
+        _ => return None,
+    })
+}
+
+struct Parser<'s> {
+    sym: &'s str,
+    next: usize,
+}
+
+impl<'s> Parser<'s> {
+    fn peek(&self) -> Option<u8> {
+        self.sym.as_bytes().get(self.next).cloned()
+    }
+
+    fn eat(&mut self, b: u8) -> bool {
+        if self.peek() == Some(b) {
+            self.next += 1;
+            true
+        } else {
+            false
+        }
+    }
+
+    fn next(&mut self) -> Result<u8, Invalid> {
+        let b = try!(self.peek().ok_or(Invalid));
+        self.next += 1;
+        Ok(b)
+    }
+
+    fn hex_nibbles(&mut self) -> Result<&'s str, Invalid> {
+        let start = self.next;
+        loop {
+            match try!(self.next()) {
+                b'0'...b'9' | b'a'...b'f' => {}
+                b'_' => break,
+                _ => return Err(Invalid),
+            }
+        }
+        Ok(&self.sym[start..self.next - 1])
+    }
+
+    fn digit_10(&mut self) -> Result<u8, Invalid> {
+        let d = match self.peek() {
+            Some(d @ b'0'...b'9') => d - b'0',
+            _ => return Err(Invalid),
+        };
+        self.next += 1;
+        Ok(d)
+    }
+
+    fn digit_62(&mut self) -> Result<u8, Invalid> {
+        let d = match self.peek() {
+            Some(d @ b'0'...b'9') => d - b'0',
+            Some(d @ b'a'...b'z') => 10 + (d - b'a'),
+            Some(d @ b'A'...b'Z') => 10 + 26 + (d - b'A'),
+            _ => return Err(Invalid),
+        };
+        self.next += 1;
+        Ok(d)
+    }
+
+    fn integer_62(&mut self) -> Result<u64, Invalid> {
+        if self.eat(b'_') {
+            return Ok(0);
+        }
+
+        let mut x: u64 = 0;
+        while !self.eat(b'_') {
+            let d = try!(self.digit_62()) as u64;
+            x = try!(x.checked_mul(62).ok_or(Invalid));
+            x = try!(x.checked_add(d).ok_or(Invalid));
+        }
+        x.checked_add(1).ok_or(Invalid)
+    }
+
+    fn opt_integer_62(&mut self, tag: u8) -> Result<u64, Invalid> {
+        if !self.eat(tag) {
+            return Ok(0);
+        }
+        try!(self.integer_62()).checked_add(1).ok_or(Invalid)
+    }
+
+    fn disambiguator(&mut self) -> Result<u64, Invalid> {
+        self.opt_integer_62(b's')
+    }
+
+    fn namespace(&mut self) -> Result<Option<char>, Invalid> {
+        match try!(self.next()) {
+            // Special namespaces, like closures and shims.
+            ns @ b'A'...b'Z' => Ok(Some(ns as char)),
+
+            // Implementation-specific/unspecified namespaces.
+            b'a'...b'z' => Ok(None),
+
+            _ => Err(Invalid),
+        }
+    }
+
+    fn backref(&mut self) -> Result<Parser<'s>, Invalid> {
+        let s_start = self.next - 1;
+        let i = try!(self.integer_62());
+        if i >= s_start as u64 {
+            return Err(Invalid);
+        }
+        Ok(Parser {
+            sym: self.sym,
+            next: i as usize,
+        })
+    }
+
+    fn ident(&mut self) -> Result<Ident<'s>, Invalid> {
+        let is_punycode = self.eat(b'u');
+        let mut len = try!(self.digit_10()) as usize;
+        if len != 0 {
+            loop {
+                match self.digit_10() {
+                    Ok(d) => {
+                        len = try!(len.checked_mul(10).ok_or(Invalid));
+                        len = try!(len.checked_add(d as usize).ok_or(Invalid));
+                    }
+                    Err(Invalid) => break,
+                }
+            }
+        }
+
+        let start = self.next;
+        self.next = try!(self.next.checked_add(len).ok_or(Invalid));
+        if self.next > self.sym.len() {
+            return Err(Invalid);
+        }
+
+        let ident = &self.sym[start..self.next];
+
+        if is_punycode {
+            let ident = match ident.bytes().rposition(|b| b == b'_') {
+                Some(i) => Ident {
+                    ascii: &ident[..i],
+                    punycode: &ident[i + 1..],
+                },
+                None => Ident {
+                    ascii: "",
+                    punycode: ident,
+                },
+            };
+            if ident.punycode.is_empty() {
+                return Err(Invalid);
+            }
+            Ok(ident)
+        } else {
+            Ok(Ident {
+                ascii: ident,
+                punycode: "",
+            })
+        }
+    }
+
+    fn skip_path(&mut self) -> Result<(), Invalid> {
+        match try!(self.next()) {
+            b'C' => {
+                try!(self.disambiguator());
+                try!(self.ident());
+            }
+            b'N' => {
+                try!(self.namespace());
+                try!(self.skip_path());
+                try!(self.disambiguator());
+                try!(self.ident());
+            }
+            b'M' => {
+                try!(self.disambiguator());
+                try!(self.skip_path());
+                try!(self.skip_type());
+            }
+            b'X' => {
+                try!(self.disambiguator());
+                try!(self.skip_path());
+                try!(self.skip_type());
+                try!(self.skip_path());
+            }
+            b'Y' => {
+                try!(self.skip_type());
+                try!(self.skip_path());
+            }
+            b'I' => {
+                try!(self.skip_path());
+                while !self.eat(b'E') {
+                    try!(self.skip_generic_arg());
+                }
+            }
+            b'B' => {
+                try!(self.backref());
+            }
+            _ => return Err(Invalid),
+        }
+        Ok(())
+    }
+
+    fn skip_generic_arg(&mut self) -> Result<(), Invalid> {
+        if self.eat(b'L') {
+            try!(self.integer_62());
+            Ok(())
+        } else if self.eat(b'K') {
+            self.skip_const()
+        } else {
+            self.skip_type()
+        }
+    }
+
+    fn skip_type(&mut self) -> Result<(), Invalid> {
+        match try!(self.next()) {
+            tag if basic_type(tag).is_some() => {}
+
+            b'R' | b'Q' => {
+                if self.eat(b'L') {
+                    try!(self.integer_62());
+                }
+                try!(self.skip_type());
+            }
+            b'P' | b'O' | b'S' => try!(self.skip_type()),
+            b'A' => {
+                try!(self.skip_type());
+                try!(self.skip_const());
+            }
+            b'T' => while !self.eat(b'E') {
+                try!(self.skip_type());
+            },
+            b'F' => {
+                let _binder = try!(self.opt_integer_62(b'G'));
+                let _is_unsafe = self.eat(b'U');
+                if self.eat(b'K') {
+                    let c_abi = self.eat(b'C');
+                    if !c_abi {
+                        let abi = try!(self.ident());
+                        if abi.ascii.is_empty() || !abi.punycode.is_empty() {
+                            return Err(Invalid);
+                        }
+                    }
+                }
+                while !self.eat(b'E') {
+                    try!(self.skip_type());
+                }
+                try!(self.skip_type());
+            }
+            b'D' => {
+                let _binder = try!(self.opt_integer_62(b'G'));
+                while !self.eat(b'E') {
+                    try!(self.skip_path());
+                    while self.eat(b'p') {
+                        try!(self.ident());
+                        try!(self.skip_type());
+                    }
+                }
+                if !self.eat(b'L') {
+                    return Err(Invalid);
+                }
+                try!(self.integer_62());
+            }
+            b'B' => {
+                try!(self.backref());
+            }
+            _ => {
+                // Go back to the tag, so `skip_path` also sees it.
+                self.next -= 1;
+                try!(self.skip_path());
+            }
+        }
+        Ok(())
+    }
+
+    fn skip_const(&mut self) -> Result<(), Invalid> {
+        if self.eat(b'B') {
+            try!(self.backref());
+            return Ok(());
+        }
+
+        match try!(self.next()) {
+            // Unsigned integer types.
+            b'h' | b't' | b'm' | b'y' | b'o' | b'j' => {}
+
+            _ => return Err(Invalid),
+        }
+
+        if self.eat(b'p') {
+            return Ok(());
+        }
+        try!(self.hex_nibbles());
+        Ok(())
+    }
+}
+
+struct Printer<'a, 'b: 'a, 's> {
+    parser: Result<Parser<'s>, Invalid>,
+    out: &'a mut fmt::Formatter<'b>,
+    bound_lifetime_depth: u32,
+}
+
+/// Mark the parser as errored, print `?` and return early.
+/// This allows callers to keep printing the approximate
+/// syntax of the path/type/const, despite having errors.
+/// E.g. `Vec<[(A, ?); ?]>` instead of `Vec<[(A, ?`.
+macro_rules! invalid {
+    ($printer:ident) => {{
+        $printer.parser = Err(Invalid);
+        return $printer.out.write_str("?");
+    }}
+}
+
+/// Call a parser method (if the parser hasn't errored yet),
+/// and mark the parser as errored if it returns `Err(Invalid)`.
+///
+/// If the parser errored, before or now, prints `?`, and
+/// returns early the current function (see `invalid!` above).
+macro_rules! parse {
+    ($printer:ident, $method:ident $(($($arg:expr),*))*) => {
+        match $printer.parser_mut().and_then(|p| p.$method($($($arg),*)*)) {
+            Ok(x) => x,
+            Err(Invalid) => invalid!($printer),
+        }
+    };
+}
+
+impl<'a, 'b, 's> Printer<'a, 'b, 's> {
+    fn parser_mut<'c>(&'c mut self) -> Result<&'c mut Parser<'s>, Invalid> {
+        self.parser.as_mut().map_err(|_| Invalid)
+    }
+
+    /// Eat the given character from the parser,
+    /// returning `false` if the parser errored.
+    fn eat(&mut self, b: u8) -> bool {
+        self.parser_mut().map(|p| p.eat(b)) == Ok(true)
+    }
+
+    /// Return a nested parser for a backref.
+    fn backref_printer<'c>(&'c mut self) -> Printer<'c, 'b, 's> {
+        Printer {
+            parser: self.parser_mut().and_then(|p| p.backref()),
+            out: self.out,
+            bound_lifetime_depth: self.bound_lifetime_depth,
+        }
+    }
+
+    /// Print the lifetime according to the previously decoded index.
+    /// An index of `0` always refers to `'_`, but starting with `1`,
+    /// indices refer to late-bound lifetimes introduced by a binder.
+    fn print_lifetime_from_index(&mut self, lt: u64) -> fmt::Result {
+        try!(self.out.write_str("'"));
+        if lt == 0 {
+            return self.out.write_str("_");
+        }
+        match (self.bound_lifetime_depth as u64).checked_sub(lt) {
+            Some(depth) => {
+                // Try to print lifetimes alphabetically first.
+                if depth < 26 {
+                    let c = (b'a' + depth as u8) as char;
+                    c.fmt(self.out)
+                } else {
+                    // Use `'_123` after running out of letters.
+                    try!(self.out.write_str("_"));
+                    depth.fmt(self.out)
+                }
+            }
+            None => invalid!(self),
+        }
+    }
+
+    /// Optionally enter a binder ('G') for late-bound lifetimes,
+    /// printing e.g. `for<'a, 'b> ` before calling the closure,
+    /// and make those lifetimes visible to it (via depth level).
+    fn in_binder<F>(&mut self, f: F) -> fmt::Result
+        where F: FnOnce(&mut Self) -> fmt::Result,
+    {
+        let bound_lifetimes = parse!(self, opt_integer_62(b'G'));
+
+        if bound_lifetimes > 0 {
+            try!(self.out.write_str("for<"));
+            for i in 0..bound_lifetimes {
+                if i > 0 {
+                    try!(self.out.write_str(", "));
+                }
+                self.bound_lifetime_depth += 1;
+                try!(self.print_lifetime_from_index(1));
+            }
+            try!(self.out.write_str("> "));
+        }
+
+        let r = f(self);
+
+        // Restore `bound_lifetime_depth` to the previous value.
+        self.bound_lifetime_depth -= bound_lifetimes as u32;
+
+        r
+    }
+
+    /// Print list elements using the given closure and separator,
+    /// until the end of the list ('E') is found, or the parser errors.
+    /// Returns the number of elements printed.
+    fn print_sep_list<F>(&mut self, f: F, sep: &str) -> Result<usize, fmt::Error>
+        where F: Fn(&mut Self) -> fmt::Result,
+    {
+        let mut i = 0;
+        while self.parser.is_ok() && !self.eat(b'E') {
+            if i > 0 {
+                try!(self.out.write_str(sep));
+            }
+            try!(f(self));
+            i += 1;
+        }
+        Ok(i)
+    }
+
+    fn print_path(&mut self, in_value: bool) -> fmt::Result {
+        let tag = parse!(self, next);
+        match tag {
+            b'C' => {
+                let dis = parse!(self, disambiguator);
+                let name = parse!(self, ident);
+
+                if name.punycode.is_empty() {
+                    // Unescape `_[0-9_]`.
+                    let mut name = name.ascii;
+                    if name.starts_with("_") {
+                        name = &name[1..];
+                    }
+                    try!(self.out.write_str(name));
+                } else {
+                    try!(name.fmt(self.out));
+                }
+                if !self.out.alternate() {
+                    try!(self.out.write_str("["));
+                    try!(fmt::LowerHex::fmt(&dis, self.out));
+                    try!(self.out.write_str("]"));
+                }
+            }
+            b'N' => {
+                let ns = parse!(self, namespace);
+
+                try!(self.print_path(in_value));
+
+                let dis = parse!(self, disambiguator);
+                let name = parse!(self, ident);
+
+                match ns {
+                    // Special namespaces, like closures and shims.
+                    Some(ns) => {
+                        try!(self.out.write_str("::{"));
+                        match ns {
+                            'C' => try!(self.out.write_str("closure")),
+                            'S' => try!(self.out.write_str("shim")),
+                            _ => try!(ns.fmt(self.out)),
+                        }
+                        if !name.ascii.is_empty() || !name.punycode.is_empty() {
+                            try!(self.out.write_str(":"));
+                            try!(name.fmt(self.out));
+                        }
+                        try!(self.out.write_str("#"));
+                        try!(dis.fmt(self.out));
+                        try!(self.out.write_str("}"));
+                    }
+
+                    // Implementation-specific/unspecified namespaces.
+                    None => {
+                        if !name.ascii.is_empty() || !name.punycode.is_empty() {
+                            try!(self.out.write_str("::"));
+                            try!(name.fmt(self.out));
+                        }
+                    }
+                }
+            }
+            b'M' | b'X' | b'Y' => {
+                if tag != b'Y' {
+                    // Ignore the `impl`'s own path.
+                    parse!(self, disambiguator);
+                    parse!(self, skip_path);
+                }
+
+                try!(self.out.write_str("<"));
+                try!(self.print_type());
+                if tag != b'M' {
+                    try!(self.out.write_str(" as "));
+                    try!(self.print_path(false));
+                }
+                try!(self.out.write_str(">"));
+            }
+            b'I' => {
+                try!(self.print_path(in_value));
+                if in_value {
+                    try!(self.out.write_str("::"));
+                }
+                try!(self.out.write_str("<"));
+                try!(self.print_sep_list(Self::print_generic_arg, ", "));
+                try!(self.out.write_str(">"));
+            }
+            b'B' => {
+                try!(self.backref_printer().print_path(in_value));
+            }
+            _ => invalid!(self),
+        }
+        Ok(())
+    }
+
+    fn print_generic_arg(&mut self) -> fmt::Result {
+        if self.eat(b'L') {
+            let lt = parse!(self, integer_62);
+            self.print_lifetime_from_index(lt)
+        } else if self.eat(b'K') {
+            self.print_const()
+        } else {
+            self.print_type()
+        }
+    }
+
+    fn print_type(&mut self) -> fmt::Result {
+        let tag = parse!(self, next);
+
+        match basic_type(tag) {
+            Some(ty) => return self.out.write_str(ty),
+            None => {}
+        }
+
+        match tag {
+            b'R' | b'Q' => {
+                try!(self.out.write_str("&"));
+                if self.eat(b'L') {
+                    let lt = parse!(self, integer_62);
+                    if lt != 0 {
+                        try!(self.print_lifetime_from_index(lt));
+                        try!(self.out.write_str(" "));
+                    }
+                }
+                if tag != b'R' {
+                    try!(self.out.write_str("mut "));
+                }
+                try!(self.print_type());
+            }
+
+            b'P' | b'O' => {
+                try!(self.out.write_str("*"));
+                if tag != b'P' {
+                    try!(self.out.write_str("mut "));
+                } else {
+                    try!(self.out.write_str("const "));
+                }
+                try!(self.print_type());
+            }
+
+            b'A' | b'S' => {
+                try!(self.out.write_str("["));
+                try!(self.print_type());
+                if tag == b'A' {
+                    try!(self.out.write_str("; "));
+                    try!(self.print_const());
+                }
+                try!(self.out.write_str("]"));
+            }
+            b'T' => {
+                try!(self.out.write_str("("));
+                let count = try!(self.print_sep_list(Self::print_type, ", "));
+                if count == 1 {
+                    try!(self.out.write_str(","));
+                }
+                try!(self.out.write_str(")"));
+            }
+            b'F' => try!(self.in_binder(|this| {
+                let is_unsafe = this.eat(b'U');
+                let abi = if this.eat(b'K') {
+                    if this.eat(b'C') {
+                        Some("C")
+                    } else {
+                        let abi = parse!(this, ident);
+                        if abi.ascii.is_empty() || !abi.punycode.is_empty() {
+                            invalid!(this);
+                        }
+                        Some(abi.ascii)
+                    }
+                } else {
+                    None
+                };
+
+                if is_unsafe {
+                    try!(this.out.write_str("unsafe "));
+                }
+
+                match abi {
+                    Some(abi) => {
+                        try!(this.out.write_str("extern \""));
+
+                        // If the ABI had any `-`, they were replaced with `_`,
+                        // so the parts between `_` have to be re-joined with `-`.
+                        let mut parts = abi.split('_');
+                        try!(this.out.write_str(parts.next().unwrap()));
+                        for part in parts {
+                            try!(this.out.write_str("-"));
+                            try!(this.out.write_str(part));
+                        }
+
+                        try!(this.out.write_str("\" "));
+                    }
+                    None => {}
+                }
+
+                try!(this.out.write_str("fn("));
+                try!(this.print_sep_list(Self::print_type, ", "));
+                try!(this.out.write_str(")"));
+
+                if this.eat(b'u') {
+                    // Skip printing the return type if it's 'u', i.e. `()`.
+                } else {
+                    try!(this.out.write_str(" -> "));
+                    try!(this.print_type());
+                }
+
+                Ok(())
+            })),
+            b'D' => {
+                try!(self.out.write_str("dyn "));
+                try!(self.in_binder(|this| {
+                    try!(this.print_sep_list(Self::print_dyn_trait, " + "));
+                    Ok(())
+                }));
+
+                if !self.eat(b'L') {
+                    invalid!(self);
+                }
+                let lt = parse!(self, integer_62);
+                if lt != 0 {
+                    try!(self.out.write_str(" + "));
+                    try!(self.print_lifetime_from_index(lt));
+                }
+            }
+            b'B' => {
+                try!(self.backref_printer().print_type());
+            }
+            _ => {
+                // Go back to the tag, so `print_path` also sees it.
+                let _ = self.parser_mut().map(|p| p.next -= 1);
+                try!(self.print_path(false));
+            }
+        }
+        Ok(())
+    }
+
+    /// A trait in a trait object may have some "existential projections"
+    /// (i.e. associated type bindings) after it, which should be printed
+    /// in the `<...>` of the trait, e.g. `dyn Trait<T, U, Assoc=X>`.
+    /// To this end, this method will keep the `<...>` of an 'I' path
+    /// open, by omitting the `>`, and return `Ok(true)` in that case.
+    fn print_path_maybe_open_generics(&mut self) -> Result<bool, fmt::Error> {
+        if self.eat(b'B') {
+            self.backref_printer().print_path_maybe_open_generics()
+        } else if self.eat(b'I') {
+            try!(self.print_path(false));
+            try!(self.out.write_str("<"));
+            try!(self.print_sep_list(Self::print_generic_arg, ", "));
+            Ok(true)
+        } else {
+            try!(self.print_path(false));
+            Ok(false)
+        }
+    }
+
+    fn print_dyn_trait(&mut self) -> fmt::Result {
+        let mut open = try!(self.print_path_maybe_open_generics());
+
+        while self.eat(b'p') {
+            if !open {
+                try!(self.out.write_str("<"));
+                open = true;
+            } else {
+                try!(self.out.write_str(", "));
+            }
+
+            let name = parse!(self, ident);
+            try!(name.fmt(self.out));
+            try!(self.out.write_str(" = "));
+            try!(self.print_type());
+        }
+
+        if open {
+            try!(self.out.write_str(">"));
+        }
+
+        Ok(())
+    }
+
+    fn print_const(&mut self) -> fmt::Result {
+        if self.eat(b'B') {
+            return self.backref_printer().print_const();
+        }
+
+        let ty_tag = parse!(self, next);
+        let ty = match ty_tag {
+            // Unsigned integer types.
+            b'h' | b't' | b'm' | b'y' | b'o' | b'j' => {
+                basic_type(ty_tag).unwrap()
+            }
+
+            _ => invalid!(self),
+        };
+
+
+        if self.eat(b'p') {
+            try!(self.out.write_str("_"));
+        } else {
+            try!(self.print_const_uint());
+        }
+
+        if !self.out.alternate() {
+            try!(self.out.write_str(": "));
+            try!(self.out.write_str(ty));
+        }
+
+        Ok(())
+    }
+
+    fn print_const_uint(&mut self) -> fmt::Result {
+        let hex = parse!(self, hex_nibbles);
+
+        // Print anything that doesn't fit in `u64` verbatim.
+        if hex.len() > 16 {
+            try!(self.out.write_str("0x"));
+            return self.out.write_str(hex);
+        }
+
+        let mut v = 0;
+        for c in hex.chars() {
+            v = (v << 4) | (c.to_digit(16).unwrap() as u64);
+        }
+        v.fmt(self.out)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    macro_rules! t_nohash {
+        ($a:expr, $b:expr) => ({
+            assert_eq!(format!("{:#}", ::demangle($a)), $b);
+        })
+    }
+
+    #[test]
+    fn demangle_utf8_idents() {
+        t_nohash!(
+            "_RNqCs4fqI2P2rA04_11utf8_identsu30___HhkackfeceaBcbdathfdhJhlqGy",
+            "utf8_idents::საჭმელად_გემრიელი_სადილი"
+        );
+    }
+
+    #[test]
+    fn demangle_closure() {
+        t_nohash!(
+            "_RNCNCNgCs6DXkGYLi8lr_2cc5spawn00B5_",
+            "cc::spawn::{closure#0}::{closure#0}"
+        );
+        t_nohash!(
+            "_RNCINkXs25_NgCsbmNqQUJIY6D_4core5sliceINyB9_4IterhENuNgNoBb_4iter8iterator8Iterator9rpositionNCNgNpB9_6memchr7memrchrs_0E0Bb_",
+            "<core::slice::Iter<u8> as core::iter::iterator::Iterator>::rposition::<core::slice::memchr::memrchr::{closure#1}>::{closure#0}"
+        );
+    }
+
+    #[test]
+    fn demangle_dyn_trait() {
+        t_nohash!(
+            "_RINbNbCskIICzLVDPPb_5alloc5alloc8box_freeDINbNiB4_5boxed5FnBoxuEp6OutputuEL_ECs1iopQbuBiw2_3std",
+            "alloc::alloc::box_free::<dyn alloc::boxed::FnBox<(), Output = ()>>"
+        );
+    }
+}
