about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-08 09:06:42 -0700
committerbors <bors@rust-lang.org>2014-05-08 09:06:42 -0700
commitaa6725407ae0a2cb88458e147e76adf8bcae0961 (patch)
treec09983e00886791c40b9304d99dd8d05e2d613c2 /src/libsyntax/parse
parente45485181338137136ea2816d78ed108440f7d50 (diff)
parent7f8f3dcf179d7b771f8e9c588ab081ab5eb9c394 (diff)
downloadrust-aa6725407ae0a2cb88458e147e76adf8bcae0961.tar.gz
rust-aa6725407ae0a2cb88458e147e76adf8bcae0961.zip
auto merge of #14032 : pcwalton/rust/detildestr, r=alexcrichton
r? @brson
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/comments.rs104
-rw-r--r--src/libsyntax/parse/lexer.rs159
-rw-r--r--src/libsyntax/parse/mod.rs70
-rw-r--r--src/libsyntax/parse/obsolete.rs2
-rw-r--r--src/libsyntax/parse/parser.rs20
-rw-r--r--src/libsyntax/parse/token.rs147
6 files changed, 273 insertions, 229 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index a96905f8597..5fc214109c2 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -33,7 +33,7 @@ pub enum CommentStyle {
 #[deriving(Clone)]
 pub struct Comment {
     pub style: CommentStyle,
-    pub lines: Vec<~str>,
+    pub lines: Vec<StrBuf>,
     pub pos: BytePos,
 }
 
@@ -53,35 +53,40 @@ pub fn doc_comment_style(comment: &str) -> ast::AttrStyle {
     }
 }
 
-pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
+pub fn strip_doc_comment_decoration(comment: &str) -> StrBuf {
     /// remove whitespace-only lines from the start/end of lines
-    fn vertical_trim(lines: Vec<~str> ) -> Vec<~str> {
+    fn vertical_trim(lines: Vec<StrBuf> ) -> Vec<StrBuf> {
         let mut i = 0u;
         let mut j = lines.len();
         // first line of all-stars should be omitted
-        if lines.len() > 0 && lines.get(0).chars().all(|c| c == '*') {
+        if lines.len() > 0 &&
+                lines.get(0).as_slice().chars().all(|c| c == '*') {
             i += 1;
         }
-        while i < j && lines.get(i).trim().is_empty() {
+        while i < j && lines.get(i).as_slice().trim().is_empty() {
             i += 1;
         }
         // like the first, a last line of all stars should be omitted
-        if j > i && lines.get(j - 1).chars().skip(1).all(|c| c == '*') {
+        if j > i && lines.get(j - 1)
+                         .as_slice()
+                         .chars()
+                         .skip(1)
+                         .all(|c| c == '*') {
             j -= 1;
         }
-        while j > i && lines.get(j - 1).trim().is_empty() {
+        while j > i && lines.get(j - 1).as_slice().trim().is_empty() {
             j -= 1;
         }
         return lines.slice(i, j).iter().map(|x| (*x).clone()).collect();
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
-    fn horizontal_trim(lines: Vec<~str> ) -> Vec<~str> {
+    fn horizontal_trim(lines: Vec<StrBuf> ) -> Vec<StrBuf> {
         let mut i = uint::MAX;
         let mut can_trim = true;
         let mut first = true;
         for line in lines.iter() {
-            for (j, c) in line.chars().enumerate() {
+            for (j, c) in line.as_slice().chars().enumerate() {
                 if j > i || !"* \t".contains_char(c) {
                     can_trim = false;
                     break;
@@ -105,7 +110,9 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
         }
 
         if can_trim {
-            lines.iter().map(|line| line.slice(i + 1, line.len()).to_owned()).collect()
+            lines.iter().map(|line| {
+                line.as_slice().slice(i + 1, line.len()).to_strbuf()
+            }).collect()
         } else {
             lines
         }
@@ -115,39 +122,41 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
     static ONLINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
     for prefix in ONLINERS.iter() {
         if comment.starts_with(*prefix) {
-            return comment.slice_from(prefix.len()).to_owned();
+            return comment.slice_from(prefix.len()).to_strbuf();
         }
     }
 
     if comment.starts_with("/*") {
         let lines = comment.slice(3u, comment.len() - 2u)
             .lines_any()
-            .map(|s| s.to_owned())
-            .collect::<Vec<~str> >();
+            .map(|s| s.to_strbuf())
+            .collect::<Vec<StrBuf> >();
 
         let lines = vertical_trim(lines);
         let lines = horizontal_trim(lines);
 
-        return lines.connect("\n");
+        return lines.connect("\n").to_strbuf();
     }
 
     fail!("not a doc-comment: {}", comment);
 }
 
-fn read_to_eol(rdr: &mut StringReader) -> ~str {
+fn read_to_eol(rdr: &mut StringReader) -> StrBuf {
     let mut val = StrBuf::new();
     while !rdr.curr_is('\n') && !is_eof(rdr) {
         val.push_char(rdr.curr.unwrap());
         bump(rdr);
     }
     if rdr.curr_is('\n') { bump(rdr); }
-    return val.into_owned();
+    return val
 }
 
-fn read_one_line_comment(rdr: &mut StringReader) -> ~str {
+fn read_one_line_comment(rdr: &mut StringReader) -> StrBuf {
     let val = read_to_eol(rdr);
-    assert!((val[0] == '/' as u8 && val[1] == '/' as u8) ||
-                 (val[0] == '#' as u8 && val[1] == '!' as u8));
+    assert!((val.as_slice()[0] == '/' as u8 &&
+                val.as_slice()[1] == '/' as u8) ||
+                (val.as_slice()[0] == '#' as u8 &&
+                 val.as_slice()[1] == '!' as u8));
     return val;
 }
 
@@ -193,11 +202,12 @@ fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool,
                       comments: &mut Vec<Comment>) {
     debug!(">>> line comments");
     let p = rdr.last_pos;
-    let mut lines: Vec<~str> = Vec::new();
+    let mut lines: Vec<StrBuf> = Vec::new();
     while rdr.curr_is('/') && nextch_is(rdr, '/') {
         let line = read_one_line_comment(rdr);
         debug!("{}", line);
-        if is_doc_comment(line) { // doc-comments are not put in comments
+        // Doc comments are not put in comments.
+        if is_doc_comment(line.as_slice()) {
             break;
         }
         lines.push(line);
@@ -231,14 +241,16 @@ fn all_whitespace(s: &str, col: CharPos) -> Option<uint> {
     return Some(cursor);
 }
 
-fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<~str> ,
-                                        s: ~str, col: CharPos) {
+fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<StrBuf> ,
+                                        s: StrBuf, col: CharPos) {
     let len = s.len();
-    let s1 = match all_whitespace(s, col) {
+    let s1 = match all_whitespace(s.as_slice(), col) {
         Some(col) => {
             if col < len {
-                s.slice(col, len).to_owned()
-            } else {  "".to_owned() }
+                s.as_slice().slice(col, len).to_strbuf()
+            } else {
+                "".to_strbuf()
+            }
         }
         None => s,
     };
@@ -251,7 +263,7 @@ fn read_block_comment(rdr: &mut StringReader,
                       comments: &mut Vec<Comment> ) {
     debug!(">>> block comment");
     let p = rdr.last_pos;
-    let mut lines: Vec<~str> = Vec::new();
+    let mut lines: Vec<StrBuf> = Vec::new();
     let col = rdr.col;
     bump(rdr);
     bump(rdr);
@@ -273,17 +285,17 @@ fn read_block_comment(rdr: &mut StringReader,
             return
         }
         assert!(!curr_line.as_slice().contains_char('\n'));
-        lines.push(curr_line.into_owned());
+        lines.push(curr_line);
     } else {
         let mut level: int = 1;
         while level > 0 {
             debug!("=== block comment level {}", level);
             if is_eof(rdr) {
-                rdr.fatal("unterminated block comment".to_owned());
+                rdr.fatal("unterminated block comment".to_strbuf());
             }
             if rdr.curr_is('\n') {
                 trim_whitespace_prefix_and_push_line(&mut lines,
-                                                     curr_line.into_owned(),
+                                                     curr_line,
                                                      col);
                 curr_line = StrBuf::new();
                 bump(rdr);
@@ -306,7 +318,7 @@ fn read_block_comment(rdr: &mut StringReader,
         }
         if curr_line.len() != 0 {
             trim_whitespace_prefix_and_push_line(&mut lines,
-                                                 curr_line.into_owned(),
+                                                 curr_line,
                                                  col);
         }
     }
@@ -344,7 +356,7 @@ fn consume_comment(rdr: &mut StringReader,
 
 #[deriving(Clone)]
 pub struct Literal {
-    pub lit: ~str,
+    pub lit: StrBuf,
     pub pos: BytePos,
 }
 
@@ -352,11 +364,11 @@ pub struct Literal {
 // probably not a good thing.
 pub fn gather_comments_and_literals(span_diagnostic:
                                         &diagnostic::SpanHandler,
-                                    path: ~str,
+                                    path: StrBuf,
                                     srdr: &mut io::Reader)
                                  -> (Vec<Comment>, Vec<Literal>) {
     let src = srdr.read_to_end().unwrap();
-    let src = str::from_utf8(src.as_slice()).unwrap().to_owned();
+    let src = str::from_utf8(src.as_slice()).unwrap().to_strbuf();
     let cm = CodeMap::new();
     let filemap = cm.new_filemap(path, src);
     let mut rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap);
@@ -387,7 +399,7 @@ pub fn gather_comments_and_literals(span_diagnostic:
         if token::is_lit(&tok) {
             with_str_from(&rdr, bstart, |s| {
                 debug!("tok lit: {}", s);
-                literals.push(Literal {lit: s.to_owned(), pos: sp.lo});
+                literals.push(Literal {lit: s.to_strbuf(), pos: sp.lo});
             })
         } else {
             debug!("tok: {}", token::to_str(&tok));
@@ -405,41 +417,41 @@ mod test {
     #[test] fn test_block_doc_comment_1() {
         let comment = "/**\n * Test \n **  Test\n *   Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test \n*  Test\n   Test".to_owned());
+        assert_eq!(stripped, " Test \n*  Test\n   Test".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_2() {
         let comment = "/**\n * Test\n *  Test\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " Test\n  Test".to_owned());
+        assert_eq!(stripped, " Test\n  Test".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_3() {
         let comment = "/**\n let a: *int;\n *a = 5;\n*/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " let a: *int;\n *a = 5;".to_owned());
+        assert_eq!(stripped, " let a: *int;\n *a = 5;".to_strbuf());
     }
 
     #[test] fn test_block_doc_comment_4() {
         let comment = "/*******************\n test\n *********************/";
         let stripped = strip_doc_comment_decoration(comment);
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
     }
 
     #[test] fn test_line_doc_comment() {
         let stripped = strip_doc_comment_decoration("/// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///! test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("// test");
-        assert_eq!(stripped, " test".to_owned());
+        assert_eq!(stripped, " test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
         let stripped = strip_doc_comment_decoration("///!test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
         let stripped = strip_doc_comment_decoration("//test");
-        assert_eq!(stripped, "test".to_owned());
+        assert_eq!(stripped, "test".to_strbuf());
     }
 }
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 43535205601..c78d2aaf3a7 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -28,7 +28,7 @@ pub use ext::tt::transcribe::{TtReader, new_tt_reader};
 pub trait Reader {
     fn is_eof(&self) -> bool;
     fn next_token(&mut self) -> TokenAndSpan;
-    fn fatal(&self, ~str) -> !;
+    fn fatal(&self, StrBuf) -> !;
     fn span_diag<'a>(&'a self) -> &'a SpanHandler;
     fn peek(&self) -> TokenAndSpan;
 }
@@ -101,8 +101,8 @@ impl<'a> Reader for StringReader<'a> {
         string_advance_token(self);
         ret_val
     }
-    fn fatal(&self, m: ~str) -> ! {
-        self.span_diagnostic.span_fatal(self.peek_span, m)
+    fn fatal(&self, m: StrBuf) -> ! {
+        self.span_diagnostic.span_fatal(self.peek_span, m.as_slice())
     }
     fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.span_diagnostic }
     fn peek(&self) -> TokenAndSpan {
@@ -123,8 +123,8 @@ impl<'a> Reader for TtReader<'a> {
         debug!("TtReader: r={:?}", r);
         r
     }
-    fn fatal(&self, m: ~str) -> ! {
-        self.sp_diag.span_fatal(self.cur_span, m);
+    fn fatal(&self, m: StrBuf) -> ! {
+        self.sp_diag.span_fatal(self.cur_span, m.as_slice());
     }
     fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.sp_diag }
     fn peek(&self) -> TokenAndSpan {
@@ -139,7 +139,7 @@ impl<'a> Reader for TtReader<'a> {
 fn fatal_span(rdr: &mut StringReader,
               from_pos: BytePos,
               to_pos: BytePos,
-              m: ~str)
+              m: StrBuf)
            -> ! {
     rdr.peek_span = codemap::mk_sp(from_pos, to_pos);
     rdr.fatal(m);
@@ -150,13 +150,13 @@ fn fatal_span(rdr: &mut StringReader,
 fn fatal_span_char(rdr: &mut StringReader,
                    from_pos: BytePos,
                    to_pos: BytePos,
-                   m: ~str,
+                   m: StrBuf,
                    c: char)
                 -> ! {
-    let mut m = StrBuf::from_owned_str(m);
+    let mut m = m;
     m.push_str(": ");
     char::escape_default(c, |c| m.push_char(c));
-    fatal_span(rdr, from_pos, to_pos, m.into_owned());
+    fatal_span(rdr, from_pos, to_pos, m.into_strbuf());
 }
 
 // report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -164,14 +164,14 @@ fn fatal_span_char(rdr: &mut StringReader,
 fn fatal_span_verbose(rdr: &mut StringReader,
                       from_pos: BytePos,
                       to_pos: BytePos,
-                      m: ~str)
+                      m: StrBuf)
                    -> ! {
-    let mut m = StrBuf::from_owned_str(m);
+    let mut m = m;
     m.push_str(": ");
     let from = byte_offset(rdr, from_pos).to_uint();
     let to = byte_offset(rdr, to_pos).to_uint();
-    m.push_str(rdr.filemap.src.slice(from, to));
-    fatal_span(rdr, from_pos, to_pos, m.into_owned());
+    m.push_str(rdr.filemap.src.as_slice().slice(from, to));
+    fatal_span(rdr, from_pos, to_pos, m);
 }
 
 // EFFECT: advance peek_tok and peek_span to refer to the next token.
@@ -218,7 +218,7 @@ fn with_str_from_to<T>(
                     end: BytePos,
                     f: |s: &str| -> T)
                     -> T {
-    f(rdr.filemap.src.slice(
+    f(rdr.filemap.src.as_slice().slice(
             byte_offset(rdr, start).to_uint(),
             byte_offset(rdr, end).to_uint()))
 }
@@ -231,7 +231,10 @@ pub fn bump(rdr: &mut StringReader) {
     if current_byte_offset < rdr.filemap.src.len() {
         assert!(rdr.curr.is_some());
         let last_char = rdr.curr.unwrap();
-        let next = rdr.filemap.src.char_range_at(current_byte_offset);
+        let next = rdr.filemap
+                      .src
+                      .as_slice()
+                      .char_range_at(current_byte_offset);
         let byte_offset_diff = next.next - current_byte_offset;
         rdr.pos = rdr.pos + Pos::from_uint(byte_offset_diff);
         rdr.curr = Some(next.ch);
@@ -256,7 +259,7 @@ pub fn is_eof(rdr: &StringReader) -> bool {
 pub fn nextch(rdr: &StringReader) -> Option<char> {
     let offset = byte_offset(rdr, rdr.pos).to_uint();
     if offset < rdr.filemap.src.len() {
-        Some(rdr.filemap.src.char_at(offset))
+        Some(rdr.filemap.src.as_slice().char_at(offset))
     } else {
         None
     }
@@ -400,9 +403,9 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
     while level > 0 {
         if is_eof(rdr) {
             let msg = if is_doc_comment {
-                "unterminated block doc-comment".to_owned()
+                "unterminated block doc-comment".to_strbuf()
             } else {
-                "unterminated block comment".to_owned()
+                "unterminated block comment".to_strbuf()
             };
             fatal_span(rdr, start_bpos, rdr.last_pos, msg);
         } else if rdr.curr_is('/') && nextch_is(rdr, '*') {
@@ -438,7 +441,7 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
     if res.is_some() { res } else { consume_whitespace_and_comments(rdr) }
 }
 
-fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
+fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<StrBuf> {
     // \x00 hits the `return None` case immediately, so this is fine.
     let mut c = rdr.curr.unwrap_or('\x00');
     let mut rslt = StrBuf::new();
@@ -452,16 +455,18 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
         }
         let exponent = scan_digits(rdr, 10u);
         if exponent.len() > 0u {
-            rslt.push_str(exponent);
-            return Some(rslt.into_owned());
+            rslt.push_str(exponent.as_slice());
+            return Some(rslt);
         } else {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "scan_exponent: bad fp literal".to_owned());
+                       "scan_exponent: bad fp literal".to_strbuf());
         }
-    } else { return None::<~str>; }
+    } else {
+        return None::<StrBuf>;
+    }
 }
 
-fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
+fn scan_digits(rdr: &mut StringReader, radix: uint) -> StrBuf {
     let mut rslt = StrBuf::new();
     loop {
         let c = rdr.curr;
@@ -471,7 +476,7 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
             rslt.push_char(c.unwrap());
             bump(rdr);
           }
-          _ => return rslt.into_owned()
+          _ => return rslt
         }
     };
 }
@@ -479,12 +484,14 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
 fn check_float_base(rdr: &mut StringReader, start_bpos: BytePos, last_bpos: BytePos,
                     base: uint) {
     match base {
-      16u => fatal_span(rdr, start_bpos, last_bpos,
-                      "hexadecimal float literal is not supported".to_owned()),
+      16u => {
+          fatal_span(rdr, start_bpos, last_bpos,
+                     "hexadecimal float literal is not supported".to_strbuf())
+      }
       8u => fatal_span(rdr, start_bpos, last_bpos,
-                     "octal float literal is not supported".to_owned()),
+                     "octal float literal is not supported".to_strbuf()),
       2u => fatal_span(rdr, start_bpos, last_bpos,
-                     "binary float literal is not supported".to_owned()),
+                     "binary float literal is not supported".to_strbuf()),
       _ => ()
     }
 }
@@ -508,7 +515,7 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         bump(rdr);
         base = 2u;
     }
-    num_str = StrBuf::from_owned_str(scan_digits(rdr, base));
+    num_str = scan_digits(rdr, base);
     c = rdr.curr.unwrap_or('\x00');
     nextch(rdr);
     if c == 'u' || c == 'i' {
@@ -544,13 +551,13 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         }
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "no valid digits found for number".to_owned());
+                       "no valid digits found for number".to_strbuf());
         }
         let parsed = match from_str_radix::<u64>(num_str.as_slice(),
                                                  base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                               "int literal is too large".to_owned())
+                               "int literal is too large".to_strbuf())
         };
 
         match tp {
@@ -564,12 +571,12 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         bump(rdr);
         let dec_part = scan_digits(rdr, 10u);
         num_str.push_char('.');
-        num_str.push_str(dec_part);
+        num_str.push_str(dec_part.as_slice());
     }
     match scan_exponent(rdr, start_bpos) {
       Some(ref s) => {
         is_float = true;
-        num_str.push_str(*s);
+        num_str.push_str(s.as_slice());
       }
       None => ()
     }
@@ -601,7 +608,7 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
             return token::LIT_FLOAT(str_to_ident(num_str.as_slice()), ast::TyF128);
         }
         fatal_span(rdr, start_bpos, rdr.last_pos,
-                   "expected `f32`, `f64` or `f128` suffix".to_owned());
+                   "expected `f32`, `f64` or `f128` suffix".to_strbuf());
     }
     if is_float {
         check_float_base(rdr, start_bpos, rdr.last_pos, base);
@@ -610,13 +617,13 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
     } else {
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "no valid digits found for number".to_owned());
+                       "no valid digits found for number".to_strbuf());
         }
         let parsed = match from_str_radix::<u64>(num_str.as_slice(),
                                                  base as uint) {
             Some(p) => p,
             None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                               "int literal is too large".to_owned())
+                               "int literal is too large".to_strbuf())
         };
 
         debug!("lexing {} as an unsuffixed integer literal",
@@ -632,9 +639,12 @@ fn scan_numeric_escape(rdr: &mut StringReader, n_hex_digits: uint) -> char {
     while i != 0u && !is_eof(rdr) {
         let n = rdr.curr;
         if !is_hex_digit(n) {
-            fatal_span_char(rdr, rdr.last_pos, rdr.pos,
-                            "illegal character in numeric character escape".to_owned(),
-                            n.unwrap());
+            fatal_span_char(
+                rdr,
+                rdr.last_pos,
+                rdr.pos,
+                "illegal character in numeric character escape".to_strbuf(),
+                n.unwrap());
         }
         bump(rdr);
         accum_int *= 16;
@@ -643,13 +653,13 @@ fn scan_numeric_escape(rdr: &mut StringReader, n_hex_digits: uint) -> char {
     }
     if i != 0 && is_eof(rdr) {
         fatal_span(rdr, start_bpos, rdr.last_pos,
-                   "unterminated numeric character escape".to_owned());
+                   "unterminated numeric character escape".to_strbuf());
     }
 
     match char::from_u32(accum_int as u32) {
         Some(x) => x,
         None => fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "illegal numeric character escape".to_owned())
+                           "illegal numeric character escape".to_strbuf())
     }
 }
 
@@ -819,11 +829,11 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
             if token::is_keyword(token::keywords::Self, tok) {
                 fatal_span(rdr, start, rdr.last_pos,
                            "invalid lifetime name: 'self \
-                            is no longer a special lifetime".to_owned());
+                            is no longer a special lifetime".to_strbuf());
             } else if token::is_any_keyword(tok) &&
                 !token::is_keyword(token::keywords::Static, tok) {
                 fatal_span(rdr, start, rdr.last_pos,
-                           "invalid lifetime name".to_owned());
+                           "invalid lifetime name".to_strbuf());
             } else {
                 return token::LIFETIME(ident);
             }
@@ -851,16 +861,24 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
                             'u' => scan_numeric_escape(rdr, 4u),
                             'U' => scan_numeric_escape(rdr, 8u),
                             c2 => {
-                                fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                                "unknown character escape".to_owned(), c2)
+                                fatal_span_char(rdr,
+                                                escaped_pos,
+                                                rdr.last_pos,
+                                                "unknown character \
+                                                 escape".to_strbuf(),
+                                                c2)
                             }
                         }
                     }
                 }
             }
             '\t' | '\n' | '\r' | '\'' => {
-                fatal_span_char(rdr, start, rdr.last_pos,
-                                "character constant must be escaped".to_owned(), c2);
+                fatal_span_char(
+                    rdr,
+                    start,
+                    rdr.last_pos,
+                    "character constant must be escaped".to_strbuf(),
+                    c2);
             }
             _ => {}
         }
@@ -871,7 +889,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
                                // ascii single quote.
                                start - BytePos(1),
                                rdr.last_pos,
-                               "unterminated character constant".to_owned());
+                               "unterminated character constant".to_strbuf());
         }
         bump(rdr); // advance curr past token
         return token::LIT_CHAR(c2);
@@ -883,7 +901,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
         while !rdr.curr_is('"') {
             if is_eof(rdr) {
                 fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated double quote string".to_owned());
+                           "unterminated double quote string".to_strbuf());
             }
 
             let ch = rdr.curr.unwrap();
@@ -892,7 +910,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
               '\\' => {
                 if is_eof(rdr) {
                     fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated double quote string".to_owned());
+                           "unterminated double quote string".to_strbuf());
                 }
 
                 let escaped = rdr.curr.unwrap();
@@ -918,7 +936,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
                   }
                   c2 => {
                     fatal_span_char(rdr, escaped_pos, rdr.last_pos,
-                                    "unknown string escape".to_owned(), c2);
+                                    "unknown string escape".to_strbuf(), c2);
                   }
                 }
               }
@@ -939,11 +957,11 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
 
         if is_eof(rdr) {
             fatal_span(rdr, start_bpos, rdr.last_pos,
-                       "unterminated raw string".to_owned());
+                       "unterminated raw string".to_strbuf());
         } else if !rdr.curr_is('"') {
             fatal_span_char(rdr, start_bpos, rdr.last_pos,
                             "only `#` is allowed in raw string delimitation; \
-                             found illegal character".to_owned(),
+                             found illegal character".to_strbuf(),
                             rdr.curr.unwrap());
         }
         bump(rdr);
@@ -952,7 +970,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
         'outer: loop {
             if is_eof(rdr) {
                 fatal_span(rdr, start_bpos, rdr.last_pos,
-                           "unterminated raw string".to_owned());
+                           "unterminated raw string".to_strbuf());
             }
             if rdr.curr_is('"') {
                 content_end_bpos = rdr.last_pos;
@@ -1000,7 +1018,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
       '%' => { return binop(rdr, token::PERCENT); }
       c => {
           fatal_span_char(rdr, rdr.last_pos, rdr.pos,
-                          "unknown start of token".to_owned(), c);
+                          "unknown start of token".to_strbuf(), c);
       }
     }
 }
@@ -1027,8 +1045,8 @@ mod test {
 
     // open a string reader for the given string
     fn setup<'a>(span_handler: &'a diagnostic::SpanHandler,
-                 teststr: ~str) -> StringReader<'a> {
-        let fm = span_handler.cm.new_filemap("zebra.rs".to_owned(), teststr);
+                 teststr: StrBuf) -> StringReader<'a> {
+        let fm = span_handler.cm.new_filemap("zebra.rs".to_strbuf(), teststr);
         new_string_reader(span_handler, fm)
     }
 
@@ -1036,7 +1054,7 @@ mod test {
         let span_handler = mk_sh();
         let mut string_reader = setup(&span_handler,
             "/* my source file */ \
-             fn main() { println!(\"zebra\"); }\n".to_owned());
+             fn main() { println!(\"zebra\"); }\n".to_strbuf());
         let id = str_to_ident("fn");
         let tok1 = string_reader.next_token();
         let tok2 = TokenAndSpan{
@@ -1069,54 +1087,56 @@ mod test {
     }
 
     #[test] fn doublecolonparsing () {
-        check_tokenization(setup(&mk_sh(), "a b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a b".to_strbuf()),
                            vec!(mk_ident("a",false),
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_2 () {
-        check_tokenization(setup(&mk_sh(), "a::b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a::b".to_strbuf()),
                            vec!(mk_ident("a",true),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_3 () {
-        check_tokenization(setup(&mk_sh(), "a ::b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a ::b".to_strbuf()),
                            vec!(mk_ident("a",false),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn dcparsing_4 () {
-        check_tokenization(setup(&mk_sh(), "a:: b".to_owned()),
+        check_tokenization(setup(&mk_sh(), "a:: b".to_strbuf()),
                            vec!(mk_ident("a",true),
                              token::MOD_SEP,
                              mk_ident("b",false)));
     }
 
     #[test] fn character_a() {
-        assert_eq!(setup(&mk_sh(), "'a'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'a'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('a'));
     }
 
     #[test] fn character_space() {
-        assert_eq!(setup(&mk_sh(), "' '".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "' '".to_strbuf()).next_token().tok,
                    token::LIT_CHAR(' '));
     }
 
     #[test] fn character_escaped() {
-        assert_eq!(setup(&mk_sh(), "'\\n'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'\\n'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('\n'));
     }
 
     #[test] fn lifetime_name() {
-        assert_eq!(setup(&mk_sh(), "'abc".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(), "'abc".to_strbuf()).next_token().tok,
                    token::LIFETIME(token::str_to_ident("abc")));
     }
 
     #[test] fn raw_string() {
-        assert_eq!(setup(&mk_sh(), "r###\"\"#a\\b\x00c\"\"###".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(),
+                         "r###\"\"#a\\b\x00c\"\"###".to_strbuf()).next_token()
+                                                                 .tok,
                    token::LIT_STR_RAW(token::str_to_ident("\"#a\\b\x00c\""), 3));
     }
 
@@ -1127,7 +1147,8 @@ mod test {
     }
 
     #[test] fn nested_block_comments() {
-        assert_eq!(setup(&mk_sh(), "/* /* */ */'a'".to_owned()).next_token().tok,
+        assert_eq!(setup(&mk_sh(),
+                         "/* /* */ */'a'".to_strbuf()).next_token().tok,
                    token::LIT_CHAR('a'));
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index dec6e6dd374..28f235a3da0 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -77,8 +77,8 @@ pub fn parse_crate_attrs_from_file(
     inner
 }
 
-pub fn parse_crate_from_source_str(name: ~str,
-                                   source: ~str,
+pub fn parse_crate_from_source_str(name: StrBuf,
+                                   source: StrBuf,
                                    cfg: ast::CrateConfig,
                                    sess: &ParseSess)
                                    -> ast::Crate {
@@ -89,8 +89,8 @@ pub fn parse_crate_from_source_str(name: ~str,
     maybe_aborted(p.parse_crate_mod(),p)
 }
 
-pub fn parse_crate_attrs_from_source_str(name: ~str,
-                                         source: ~str,
+pub fn parse_crate_attrs_from_source_str(name: StrBuf,
+                                         source: StrBuf,
                                          cfg: ast::CrateConfig,
                                          sess: &ParseSess)
                                          -> Vec<ast::Attribute> {
@@ -102,8 +102,8 @@ pub fn parse_crate_attrs_from_source_str(name: ~str,
     inner
 }
 
-pub fn parse_expr_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_expr_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> @ast::Expr {
@@ -111,8 +111,8 @@ pub fn parse_expr_from_source_str(name: ~str,
     maybe_aborted(p.parse_expr(), p)
 }
 
-pub fn parse_item_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_item_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> Option<@ast::Item> {
@@ -121,8 +121,8 @@ pub fn parse_item_from_source_str(name: ~str,
     maybe_aborted(p.parse_item(attrs),p)
 }
 
-pub fn parse_meta_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_meta_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   sess: &ParseSess)
                                   -> @ast::MetaItem {
@@ -130,8 +130,8 @@ pub fn parse_meta_from_source_str(name: ~str,
     maybe_aborted(p.parse_meta_item(),p)
 }
 
-pub fn parse_stmt_from_source_str(name: ~str,
-                                  source: ~str,
+pub fn parse_stmt_from_source_str(name: StrBuf,
+                                  source: StrBuf,
                                   cfg: ast::CrateConfig,
                                   attrs: Vec<ast::Attribute> ,
                                   sess: &ParseSess)
@@ -145,8 +145,8 @@ pub fn parse_stmt_from_source_str(name: ~str,
     maybe_aborted(p.parse_stmt(attrs),p)
 }
 
-pub fn parse_tts_from_source_str(name: ~str,
-                                 source: ~str,
+pub fn parse_tts_from_source_str(name: StrBuf,
+                                 source: StrBuf,
                                  cfg: ast::CrateConfig,
                                  sess: &ParseSess)
                                  -> Vec<ast::TokenTree> {
@@ -164,8 +164,8 @@ pub fn parse_tts_from_source_str(name: ~str,
 // Create a new parser from a source string
 pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
                                       cfg: ast::CrateConfig,
-                                      name: ~str,
-                                      source: ~str)
+                                      name: StrBuf,
+                                      source: StrBuf)
                                       -> Parser<'a> {
     filemap_to_parser(sess, string_to_filemap(sess, source, name), cfg)
 }
@@ -225,8 +225,8 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     };
     match str::from_utf8(bytes.as_slice()) {
         Some(s) => {
-            return string_to_filemap(sess, s.to_owned(),
-                                     path.as_str().unwrap().to_str())
+            return string_to_filemap(sess, s.to_strbuf(),
+                                     path.as_str().unwrap().to_strbuf())
         }
         None => err(format!("{} is not UTF-8 encoded", path.display())),
     }
@@ -235,7 +235,7 @@ pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
 
 // given a session and a string, add the string to
 // the session's codemap and return the new filemap
-pub fn string_to_filemap(sess: &ParseSess, source: ~str, path: ~str)
+pub fn string_to_filemap(sess: &ParseSess, source: StrBuf, path: StrBuf)
                          -> Rc<FileMap> {
     sess.span_diagnostic.cm.new_filemap(path, source)
 }
@@ -284,11 +284,11 @@ mod test {
     use util::parser_testing::{string_to_expr, string_to_item};
     use util::parser_testing::string_to_stmt;
 
-    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> ~str {
+    fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> StrBuf {
         let mut writer = MemWriter::new();
         let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
         let _ = val.encode(&mut encoder);
-        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_owned()
+        str::from_utf8(writer.unwrap().as_slice()).unwrap().to_strbuf()
     }
 
     // produce a codemap::span
@@ -297,7 +297,7 @@ mod test {
     }
 
     #[test] fn path_exprs_1() {
-        assert!(string_to_expr("a".to_owned()) ==
+        assert!(string_to_expr("a".to_strbuf()) ==
                    @ast::Expr{
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprPath(ast::Path {
@@ -316,7 +316,7 @@ mod test {
     }
 
     #[test] fn path_exprs_2 () {
-        assert!(string_to_expr("::a::b".to_owned()) ==
+        assert!(string_to_expr("::a::b".to_strbuf()) ==
                    @ast::Expr {
                     id: ast::DUMMY_NODE_ID,
                     node: ast::ExprPath(ast::Path {
@@ -341,12 +341,12 @@ mod test {
 
     #[should_fail]
     #[test] fn bad_path_expr_1() {
-        string_to_expr("::abc::def::return".to_owned());
+        string_to_expr("::abc::def::return".to_strbuf());
     }
 
     // check the token-tree-ization of macros
     #[test] fn string_to_tts_macro () {
-        let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_owned());
+        let tts = string_to_tts("macro_rules! zip (($a)=>($a))".to_strbuf());
         let tts: &[ast::TokenTree] = tts.as_slice();
         match tts {
             [ast::TTTok(_,_),
@@ -399,7 +399,7 @@ mod test {
     }
 
     #[test] fn string_to_tts_1 () {
-        let tts = string_to_tts("fn a (b : int) { b; }".to_owned());
+        let tts = string_to_tts("fn a (b : int) { b; }".to_strbuf());
         assert_eq!(to_json_str(&tts),
         "[\
     {\
@@ -523,12 +523,12 @@ mod test {
             ]\
         ]\
     }\
-]".to_owned()
+]".to_strbuf()
         );
     }
 
     #[test] fn ret_expr() {
-        assert!(string_to_expr("return d".to_owned()) ==
+        assert!(string_to_expr("return d".to_strbuf()) ==
                    @ast::Expr{
                     id: ast::DUMMY_NODE_ID,
                     node:ast::ExprRet(Some(@ast::Expr{
@@ -551,7 +551,7 @@ mod test {
     }
 
     #[test] fn parse_stmt_1 () {
-        assert!(string_to_stmt("b;".to_owned()) ==
+        assert!(string_to_stmt("b;".to_strbuf()) ==
                    @Spanned{
                        node: ast::StmtExpr(@ast::Expr {
                            id: ast::DUMMY_NODE_ID,
@@ -578,7 +578,7 @@ mod test {
 
     #[test] fn parse_ident_pat () {
         let sess = new_parse_sess();
-        let mut parser = string_to_parser(&sess, "b".to_owned());
+        let mut parser = string_to_parser(&sess, "b".to_strbuf());
         assert!(parser.parse_pat() ==
                    @ast::Pat{id: ast::DUMMY_NODE_ID,
                              node: ast::PatIdent(
@@ -602,7 +602,7 @@ mod test {
     // check the contents of the tt manually:
     #[test] fn parse_fundecl () {
         // this test depends on the intern order of "fn" and "int"
-        assert!(string_to_item("fn a (b : int) { b; }".to_owned()) ==
+        assert!(string_to_item("fn a (b : int) { b; }".to_strbuf()) ==
                   Some(
                       @ast::Item{ident:str_to_ident("a"),
                             attrs:Vec::new(),
@@ -694,13 +694,13 @@ mod test {
 
     #[test] fn parse_exprs () {
         // just make sure that they parse....
-        string_to_expr("3 + 4".to_owned());
-        string_to_expr("a::z.froob(b,@(987+3))".to_owned());
+        string_to_expr("3 + 4".to_strbuf());
+        string_to_expr("a::z.froob(b,@(987+3))".to_strbuf());
     }
 
     #[test] fn attrs_fix_bug () {
         string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-                   -> Result<@Writer, ~str> {
+                   -> Result<@Writer, StrBuf> {
     #[cfg(windows)]
     fn wb() -> c_int {
       (O_WRONLY | libc::consts::os::extra::O_BINARY) as c_int
@@ -710,7 +710,7 @@ mod test {
     fn wb() -> c_int { O_WRONLY as c_int }
 
     let mut fflags: c_int = wb();
-}".to_owned());
+}".to_strbuf());
     }
 
 }
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index b9157e0043d..b6aa47128e6 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -123,7 +123,7 @@ impl<'a> ParserObsoleteMethods for Parser<'a> {
             ),
             ObsoleteManagedString => (
                 "managed string",
-                "use `Rc<~str>` instead of a managed string"
+                "use `Rc<StrBuf>` instead of a managed string"
             ),
             ObsoleteManagedVec => (
                 "managed vector",
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 38f3841f15a..8f3b77dd58c 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -345,12 +345,12 @@ fn is_plain_ident_or_underscore(t: &token::Token) -> bool {
 
 impl<'a> Parser<'a> {
     // convert a token to a string using self's reader
-    pub fn token_to_str(token: &token::Token) -> ~str {
+    pub fn token_to_str(token: &token::Token) -> StrBuf {
         token::to_str(token)
     }
 
     // convert the current token to a string using self's reader
-    pub fn this_token_to_str(&mut self) -> ~str {
+    pub fn this_token_to_str(&mut self) -> StrBuf {
         Parser::token_to_str(&self.token)
     }
 
@@ -385,11 +385,17 @@ impl<'a> Parser<'a> {
     pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) {
-        fn tokens_to_str(tokens: &[token::Token]) -> ~str {
+        fn tokens_to_str(tokens: &[token::Token]) -> StrBuf {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
-            let b = i.next().map_or("".to_owned(), |t| Parser::token_to_str(t));
-            i.fold(b, |b,a| b + "`, `" + Parser::token_to_str(a))
+            let b = i.next()
+                     .map_or("".to_strbuf(), |t| Parser::token_to_str(t));
+            i.fold(b, |b,a| {
+                let mut b = b;
+                b.push_str("`, `");
+                b.push_str(Parser::token_to_str(a).as_slice());
+                b
+            })
         }
         if edible.contains(&self.token) {
             self.bump();
@@ -3898,7 +3904,7 @@ impl<'a> Parser<'a> {
         (ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
     }
 
-    // parse a::B<~str,int>
+    // parse a::B<StrBuf,int>
     fn parse_trait_ref(&mut self) -> TraitRef {
         ast::TraitRef {
             path: self.parse_path(LifetimeAndTypesWithoutColons).path,
@@ -3906,7 +3912,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // parse B + C<~str,int> + D
+    // parse B + C<StrBuf,int> + D
     fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
         self.parse_seq_to_before_end(
             ket,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 131e744d83d..8fb2fe61b83 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -137,58 +137,62 @@ impl fmt::Show for Nonterminal {
     }
 }
 
-pub fn binop_to_str(o: BinOp) -> ~str {
+pub fn binop_to_str(o: BinOp) -> StrBuf {
     match o {
-      PLUS => "+".to_owned(),
-      MINUS => "-".to_owned(),
-      STAR => "*".to_owned(),
-      SLASH => "/".to_owned(),
-      PERCENT => "%".to_owned(),
-      CARET => "^".to_owned(),
-      AND => "&".to_owned(),
-      OR => "|".to_owned(),
-      SHL => "<<".to_owned(),
-      SHR => ">>".to_owned()
+      PLUS => "+".to_strbuf(),
+      MINUS => "-".to_strbuf(),
+      STAR => "*".to_strbuf(),
+      SLASH => "/".to_strbuf(),
+      PERCENT => "%".to_strbuf(),
+      CARET => "^".to_strbuf(),
+      AND => "&".to_strbuf(),
+      OR => "|".to_strbuf(),
+      SHL => "<<".to_strbuf(),
+      SHR => ">>".to_strbuf()
     }
 }
 
-pub fn to_str(t: &Token) -> ~str {
+pub fn to_str(t: &Token) -> StrBuf {
     match *t {
-      EQ => "=".to_owned(),
-      LT => "<".to_owned(),
-      LE => "<=".to_owned(),
-      EQEQ => "==".to_owned(),
-      NE => "!=".to_owned(),
-      GE => ">=".to_owned(),
-      GT => ">".to_owned(),
-      NOT => "!".to_owned(),
-      TILDE => "~".to_owned(),
-      OROR => "||".to_owned(),
-      ANDAND => "&&".to_owned(),
+      EQ => "=".to_strbuf(),
+      LT => "<".to_strbuf(),
+      LE => "<=".to_strbuf(),
+      EQEQ => "==".to_strbuf(),
+      NE => "!=".to_strbuf(),
+      GE => ">=".to_strbuf(),
+      GT => ">".to_strbuf(),
+      NOT => "!".to_strbuf(),
+      TILDE => "~".to_strbuf(),
+      OROR => "||".to_strbuf(),
+      ANDAND => "&&".to_strbuf(),
       BINOP(op) => binop_to_str(op),
-      BINOPEQ(op) => binop_to_str(op) + "=",
+      BINOPEQ(op) => {
+          let mut s = binop_to_str(op);
+          s.push_str("=");
+          s
+      }
 
       /* Structural symbols */
-      AT => "@".to_owned(),
-      DOT => ".".to_owned(),
-      DOTDOT => "..".to_owned(),
-      DOTDOTDOT => "...".to_owned(),
-      COMMA => ",".to_owned(),
-      SEMI => ";".to_owned(),
-      COLON => ":".to_owned(),
-      MOD_SEP => "::".to_owned(),
-      RARROW => "->".to_owned(),
-      LARROW => "<-".to_owned(),
-      DARROW => "<->".to_owned(),
-      FAT_ARROW => "=>".to_owned(),
-      LPAREN => "(".to_owned(),
-      RPAREN => ")".to_owned(),
-      LBRACKET => "[".to_owned(),
-      RBRACKET => "]".to_owned(),
-      LBRACE => "{".to_owned(),
-      RBRACE => "}".to_owned(),
-      POUND => "#".to_owned(),
-      DOLLAR => "$".to_owned(),
+      AT => "@".to_strbuf(),
+      DOT => ".".to_strbuf(),
+      DOTDOT => "..".to_strbuf(),
+      DOTDOTDOT => "...".to_strbuf(),
+      COMMA => ",".to_strbuf(),
+      SEMI => ";".to_strbuf(),
+      COLON => ":".to_strbuf(),
+      MOD_SEP => "::".to_strbuf(),
+      RARROW => "->".to_strbuf(),
+      LARROW => "<-".to_strbuf(),
+      DARROW => "<->".to_strbuf(),
+      FAT_ARROW => "=>".to_strbuf(),
+      LPAREN => "(".to_strbuf(),
+      RPAREN => ")".to_strbuf(),
+      LBRACKET => "[".to_strbuf(),
+      RBRACKET => "]".to_strbuf(),
+      LBRACE => "{".to_strbuf(),
+      RBRACE => "}".to_strbuf(),
+      POUND => "#".to_strbuf(),
+      DOLLAR => "$".to_strbuf(),
 
       /* Literals */
       LIT_CHAR(c) => {
@@ -197,63 +201,64 @@ pub fn to_str(t: &Token) -> ~str {
               res.push_char(c);
           });
           res.push_char('\'');
-          res.into_owned()
+          res
       }
       LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)),
       LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)),
-      LIT_INT_UNSUFFIXED(i) => { i.to_str() }
+      LIT_INT_UNSUFFIXED(i) => { i.to_str().to_strbuf() }
       LIT_FLOAT(s, t) => {
         let mut body = StrBuf::from_str(get_ident(s).get());
         if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body.push_str(ast_util::float_ty_to_str(t));
-        body.into_owned()
+        body.push_str(ast_util::float_ty_to_str(t).as_slice());
+        body
       }
       LIT_FLOAT_UNSUFFIXED(s) => {
         let mut body = StrBuf::from_str(get_ident(s).get());
         if body.as_slice().ends_with(".") {
             body.push_char('0');  // `10.f` is not a float literal
         }
-        body.into_owned()
+        body
       }
       LIT_STR(s) => {
-          format!("\"{}\"", get_ident(s).get().escape_default())
+          (format!("\"{}\"", get_ident(s).get().escape_default())).to_strbuf()
       }
       LIT_STR_RAW(s, n) => {
-          format!("r{delim}\"{string}\"{delim}",
-                  delim="#".repeat(n), string=get_ident(s))
+          (format!("r{delim}\"{string}\"{delim}",
+                  delim="#".repeat(n), string=get_ident(s))).to_strbuf()
       }
 
       /* Name components */
-      IDENT(s, _) => get_ident(s).get().to_str(),
+      IDENT(s, _) => get_ident(s).get().to_strbuf(),
       LIFETIME(s) => {
-          format!("'{}", get_ident(s))
+          (format!("'{}", get_ident(s))).to_strbuf()
       }
-      UNDERSCORE => "_".to_owned(),
+      UNDERSCORE => "_".to_strbuf(),
 
       /* Other */
-      DOC_COMMENT(s) => get_ident(s).get().to_str(),
-      EOF => "<eof>".to_owned(),
+      DOC_COMMENT(s) => get_ident(s).get().to_strbuf(),
+      EOF => "<eof>".to_strbuf(),
       INTERPOLATED(ref nt) => {
         match nt {
             &NtExpr(e) => ::print::pprust::expr_to_str(e),
             &NtMeta(e) => ::print::pprust::meta_item_to_str(e),
             _ => {
-                "an interpolated ".to_owned() +
-                    match *nt {
-                        NtItem(..) => "item".to_owned(),
-                        NtBlock(..) => "block".to_owned(),
-                        NtStmt(..) => "statement".to_owned(),
-                        NtPat(..) => "pattern".to_owned(),
-                        NtMeta(..) => fail!("should have been handled"),
-                        NtExpr(..) => fail!("should have been handled above"),
-                        NtTy(..) => "type".to_owned(),
-                        NtIdent(..) => "identifier".to_owned(),
-                        NtPath(..) => "path".to_owned(),
-                        NtTT(..) => "tt".to_owned(),
-                        NtMatchers(..) => "matcher sequence".to_owned()
-                    }
+                let mut s = "an interpolated ".to_strbuf();
+                match *nt {
+                    NtItem(..) => s.push_str("item"),
+                    NtBlock(..) => s.push_str("block"),
+                    NtStmt(..) => s.push_str("statement"),
+                    NtPat(..) => s.push_str("pattern"),
+                    NtMeta(..) => fail!("should have been handled"),
+                    NtExpr(..) => fail!("should have been handled above"),
+                    NtTy(..) => s.push_str("type"),
+                    NtIdent(..) => s.push_str("identifier"),
+                    NtPath(..) => s.push_str("path"),
+                    NtTT(..) => s.push_str("tt"),
+                    NtMatchers(..) => s.push_str("matcher sequence")
+                };
+                s
             }
         }
       }