diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index e3a996e33d39..bfe5d5187d79 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -103,8 +103,13 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool { ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty) } +/// Generates a unique symbol based off the name given. This is used to create +/// unique symbols for things like closures. pub fn gensym_name(name: &str) -> PathElem { - PathName(token::gensym(name)) + let num = token::gensym(name); + // use one colon which will get translated to a period by the mangler, and + // we're guaranteed that `num` is globally unique for this crate. + PathName(token::gensym(format!("{}:{}", name, num))) } pub struct tydesc_info { diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index fc91d8189f01..831f6c73e35f 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -91,8 +91,47 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> { rest = rest.slice_from(1); } let i: uint = from_str(s.slice_to(s.len() - rest.len())).unwrap(); - try!(writer.write_str(rest.slice_to(i))); s = rest.slice_from(i); + rest = rest.slice_to(i); + loop { + if rest.starts_with("$") { + macro_rules! demangle( + ($($pat:expr => $demangled:expr),*) => ({ + $(if rest.starts_with($pat) { + try!(writer.write_str($demangled)); + rest = rest.slice_from($pat.len()); + } else)* + { + try!(writer.write_str(rest)); + break; + } + + }) + ) + // see src/librustc/back/link.rs for these mappings + demangle! ( + "$SP$" => "@", + "$UP$" => "~", + "$RP$" => "*", + "$BP$" => "&", + "$LT$" => "<", + "$GT$" => ">", + "$LP$" => "(", + "$RP$" => ")", + "$C$" => ",", + + // in theory we can demangle any unicode code point, but + // for simplicity we just catch the common ones. + "$x20" => " ", + "$x27" => "'", + "$x5b" => "[", + "$x5d" => "]" + ) + } else { + try!(writer.write_str(rest)); + break; + } + } } } @@ -698,17 +737,25 @@ mod test { use io::MemWriter; use str; + macro_rules! t( ($a:expr, $b:expr) => ({ + let mut m = MemWriter::new(); + super::demangle(&mut m, $a).unwrap(); + assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned()); + }) ) + #[test] fn demangle() { - macro_rules! t( ($a:expr, $b:expr) => ({ - let mut m = MemWriter::new(); - super::demangle(&mut m, $a); - assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned()); - }) ) - t!("test", "test"); t!("_ZN4testE", "test"); t!("_ZN4test", "_ZN4test"); t!("_ZN4test1a2bcE", "test::a::bc"); } + + #[test] + fn demangle_dollars() { + t!("_ZN4$UP$E", "~"); + t!("_ZN8$UP$testE", "~test"); + t!("_ZN8$UP$test4foobE", "~test::foob"); + t!("_ZN8$x20test4foobE", " test::foob"); + } }