about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-10 21:01:41 -0700
committerbors <bors@rust-lang.org>2014-04-10 21:01:41 -0700
commitcea8def62068b405495ecd1810124ebc88b4f90b (patch)
tree65d5755bd532a9213799c52572db6d6683d5e942 /src/libsyntax
parent0156af156d70efd5a3c96d0c5b8fc9bec39a7ae5 (diff)
parentdef90f43e2df9968cda730a2a30cb7ccb9513002 (diff)
downloadrust-cea8def62068b405495ecd1810124ebc88b4f90b.tar.gz
rust-cea8def62068b405495ecd1810124ebc88b4f90b.zip
auto merge of #13440 : huonw/rust/strbuf, r=alexcrichton
libstd: Implement `StrBuf`, a new string buffer type like `Vec`, and port all code over to use it.

Rebased & tests-fixed version of https://github.com/mozilla/rust/pull/13269
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_map.rs7
-rw-r--r--src/libsyntax/ast_util.rs5
-rw-r--r--src/libsyntax/codemap.rs11
-rw-r--r--src/libsyntax/diagnostic.rs32
-rw-r--r--src/libsyntax/ext/concat.rs11
-rw-r--r--src/libsyntax/ext/concat_idents.rs6
-rw-r--r--src/libsyntax/ext/deriving/show.rs6
-rw-r--r--src/libsyntax/parse/comments.rs24
-rw-r--r--src/libsyntax/parse/lexer.rs42
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/libsyntax/parse/token.rs18
-rw-r--r--src/libsyntax/print/pp.rs13
-rw-r--r--src/libsyntax/print/pprust.rs9
13 files changed, 118 insertions, 75 deletions
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index cf584ff62ac..4c7803f022a 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -19,9 +19,10 @@ use print::pprust;
 use util::small_vector::SmallVector;
 
 use std::cell::RefCell;
+use std::fmt;
 use std::iter;
 use std::slice;
-use std::fmt;
+use std::strbuf::StrBuf;
 
 #[deriving(Clone, Eq)]
 pub enum PathElem {
@@ -81,14 +82,14 @@ pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
 pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> ~str {
     let itr = token::get_ident_interner();
 
-    path.fold(~"", |mut s, e| {
+    path.fold(StrBuf::new(), |mut s, e| {
         let e = itr.get(e.name());
         if !s.is_empty() {
             s.push_str("::");
         }
         s.push_str(e.as_slice());
         s
-    })
+    }).into_owned()
 }
 
 #[deriving(Clone)]
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 55864205996..5f669d5d613 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -21,6 +21,7 @@ use visit;
 
 use std::cell::Cell;
 use std::cmp;
+use std::strbuf::StrBuf;
 use std::u32;
 
 pub fn path_name_i(idents: &[Ident]) -> ~str {
@@ -235,7 +236,7 @@ pub fn unguarded_pat(a: &Arm) -> Option<Vec<@Pat> > {
 /// listed as `__extensions__::method_name::hash`, with no indication
 /// of the type).
 pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
-    let mut pretty = pprust::ty_to_str(ty);
+    let mut pretty = StrBuf::from_owned_str(pprust::ty_to_str(ty));
     match *trait_ref {
         Some(ref trait_ref) => {
             pretty.push_char('.');
@@ -243,7 +244,7 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
         }
         None => {}
     }
-    token::gensym_ident(pretty)
+    token::gensym_ident(pretty.as_slice())
 }
 
 pub fn public_methods(ms: Vec<@Method> ) -> Vec<@Method> {
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 7cadce54765..b174dffdfec 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -21,9 +21,10 @@ source code snippets, etc.
 
 */
 
+use serialize::{Encodable, Decodable, Encoder, Decoder};
 use std::cell::RefCell;
 use std::rc::Rc;
-use serialize::{Encodable, Decodable, Encoder, Decoder};
+use std::strbuf::StrBuf;
 
 pub trait Pos {
     fn from_uint(n: uint) -> Self;
@@ -305,22 +306,22 @@ impl CodeMap {
         // FIXME #12884: no efficient/safe way to remove from the start of a string
         // and reuse the allocation.
         let mut src = if src.starts_with("\ufeff") {
-            src.as_slice().slice_from(3).into_owned()
+            StrBuf::from_str(src.as_slice().slice_from(3))
         } else {
-            src
+            StrBuf::from_owned_str(src)
         };
 
         // Append '\n' in case it's not already there.
         // This is a workaround to prevent CodeMap.lookup_filemap_idx from accidentally
         // overflowing into the next filemap in case the last byte of span is also the last
         // byte of filemap, which leads to incorrect results from CodeMap.span_to_*.
-        if src.len() > 0 && !src.ends_with("\n") {
+        if src.len() > 0 && !src.as_slice().ends_with("\n") {
             src.push_char('\n');
         }
 
         let filemap = Rc::new(FileMap {
             name: filename,
-            src: src,
+            src: src.into_owned(),
             start_pos: Pos::from_uint(start_pos),
             lines: RefCell::new(Vec::new()),
             multibyte_chars: RefCell::new(Vec::new()),
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index b11c99d1a70..e63f2960421 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -17,6 +17,7 @@ use std::cell::{RefCell, Cell};
 use std::fmt;
 use std::io;
 use std::iter::range;
+use std::strbuf::StrBuf;
 use term;
 
 // maximum number of lines we will print for each error; arbitrary.
@@ -368,11 +369,13 @@ fn highlight_lines(err: &mut EmitterWriter,
 
         // indent past |name:## | and the 0-offset column location
         let left = fm.name.len() + digits + lo.col.to_uint() + 3u;
-        let mut s = ~"";
+        let mut s = StrBuf::new();
         // Skip is the number of characters we need to skip because they are
         // part of the 'filename:line ' part of the previous line.
         let skip = fm.name.len() + digits + 3u;
-        for _ in range(0, skip) { s.push_char(' '); }
+        for _ in range(0, skip) {
+            s.push_char(' ');
+        }
         let orig = fm.get_line(*lines.lines.get(0) as int);
         for pos in range(0u, left-skip) {
             let cur_char = orig[pos] as char;
@@ -386,14 +389,16 @@ fn highlight_lines(err: &mut EmitterWriter,
             };
         }
         try!(write!(&mut err.dst, "{}", s));
-        let mut s = ~"^";
+        let mut s = StrBuf::from_str("^");
         let hi = cm.lookup_char_pos(sp.hi);
         if hi.col != lo.col {
             // the ^ already takes up one space
             let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
-            for _ in range(0, num_squigglies) { s.push_char('~'); }
+            for _ in range(0, num_squigglies) {
+                s.push_char('~');
+            }
         }
-        try!(print_maybe_styled(err, s + "\n",
+        try!(print_maybe_styled(err, s.into_owned() + "\n",
                                 term::attr::ForegroundColor(lvl.color())));
     }
     Ok(())
@@ -409,7 +414,8 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
                           cm: &codemap::CodeMap,
                           sp: Span,
                           lvl: Level,
-                          lines: codemap::FileLines) -> io::IoResult<()> {
+                          lines: codemap::FileLines)
+                          -> io::IoResult<()> {
     let fm = &*lines.file;
 
     let lines = lines.lines.as_slice();
@@ -430,15 +436,21 @@ fn custom_highlight_lines(w: &mut EmitterWriter,
     let hi = cm.lookup_char_pos(sp.hi);
     // Span seems to use half-opened interval, so subtract 1
     let skip = last_line_start.len() + hi.col.to_uint() - 1;
-    let mut s = ~"";
-    for _ in range(0, skip) { s.push_char(' '); }
+    let mut s = StrBuf::new();
+    for _ in range(0, skip) {
+        s.push_char(' ');
+    }
     s.push_char('^');
-    print_maybe_styled(w, s + "\n", term::attr::ForegroundColor(lvl.color()))
+    s.push_char('\n');
+    print_maybe_styled(w,
+                       s.into_owned(),
+                       term::attr::ForegroundColor(lvl.color()))
 }
 
 fn print_macro_backtrace(w: &mut EmitterWriter,
                          cm: &codemap::CodeMap,
-                         sp: Span) -> io::IoResult<()> {
+                         sp: Span)
+                         -> io::IoResult<()> {
     for ei in sp.expn_info.iter() {
         let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
         let (pre, post) = match ei.callee.format {
diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs
index e638291ecfa..1db65e3b9e4 100644
--- a/src/libsyntax/ext/concat.rs
+++ b/src/libsyntax/ext/concat.rs
@@ -8,14 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::char;
-
 use ast;
 use codemap;
 use ext::base;
 use ext::build::AstBuilder;
 use parse::token;
 
+use std::char;
+use std::strbuf::StrBuf;
+
 pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                          sp: codemap::Span,
                          tts: &[ast::TokenTree]) -> base::MacResult {
@@ -23,7 +24,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
         Some(e) => e,
         None => return base::MacResult::dummy_expr(sp)
     };
-    let mut accumulator = ~"";
+    let mut accumulator = StrBuf::new();
     for e in es.move_iter() {
         match e.node {
             ast::ExprLit(lit) => {
@@ -56,5 +57,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
             }
         }
     }
-    base::MRExpr(cx.expr_str(sp, token::intern_and_get_ident(accumulator)))
+    base::MRExpr(cx.expr_str(
+            sp,
+            token::intern_and_get_ident(accumulator.into_owned())))
 }
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index 8441fa719ea..a5faa693982 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -16,9 +16,11 @@ use owned_slice::OwnedSlice;
 use parse::token;
 use parse::token::{str_to_ident};
 
+use std::strbuf::StrBuf;
+
 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     -> base::MacResult {
-    let mut res_str = ~"";
+    let mut res_str = StrBuf::new();
     for (i, e) in tts.iter().enumerate() {
         if i & 1 == 1 {
             match *e {
@@ -40,7 +42,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             }
         }
     }
-    let res = str_to_ident(res_str);
+    let res = str_to_ident(res_str.into_owned());
 
     let e = @ast::Expr {
         id: ast::DUMMY_NODE_ID,
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 1c80fb9ced2..067958e4bde 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -15,10 +15,10 @@ use ext::format;
 use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
-
 use parse::token;
 
 use collections::HashMap;
+use std::strbuf::StrBuf;
 
 pub fn expand_deriving_show(cx: &mut ExtCtxt,
                             span: Span,
@@ -68,7 +68,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
         }
     };
 
-    let mut format_string = token::get_ident(name).get().to_owned();
+    let mut format_string = StrBuf::from_str(token::get_ident(name).get());
     // the internal fields we're actually formatting
     let mut exprs = Vec::new();
 
@@ -129,7 +129,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let write_call = cx.expr_call_global(span, std_write, vec!(buf, cx.expr_ident(span, args)));
     let format_closure = cx.lambda_expr(span, vec!(args), write_call);
 
-    let s = token::intern_and_get_ident(format_string);
+    let s = token::intern_and_get_ident(format_string.as_slice());
     let format_string = cx.expr_str(span, s);
 
     // phew, not our responsibility any more!
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index bb812f7f6b4..1a246eb7f2c 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -19,6 +19,7 @@ use parse::token;
 
 use std::io;
 use std::str;
+use std::strbuf::StrBuf;
 use std::uint;
 
 #[deriving(Clone, Eq)]
@@ -134,13 +135,13 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
 }
 
 fn read_to_eol(rdr: &mut StringReader) -> ~str {
-    let mut val = ~"";
+    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;
+    return val.into_owned();
 }
 
 fn read_one_line_comment(rdr: &mut StringReader) -> ~str {
@@ -255,7 +256,7 @@ fn read_block_comment(rdr: &mut StringReader,
     bump(rdr);
     bump(rdr);
 
-    let mut curr_line = ~"/*";
+    let mut curr_line = StrBuf::from_str("/*");
 
     // doc-comments are not really comments, they are attributes
     if (rdr.curr_is('*') && !nextch_is(rdr, '*')) || rdr.curr_is('!') {
@@ -268,9 +269,11 @@ fn read_block_comment(rdr: &mut StringReader,
             bump(rdr);
             bump(rdr);
         }
-        if !is_block_non_doc_comment(curr_line) { return; }
-        assert!(!curr_line.contains_char('\n'));
-        lines.push(curr_line);
+        if !is_block_non_doc_comment(curr_line.as_slice()) {
+            return
+        }
+        assert!(!curr_line.as_slice().contains_char('\n'));
+        lines.push(curr_line.into_owned());
     } else {
         let mut level: int = 1;
         while level > 0 {
@@ -279,9 +282,10 @@ fn read_block_comment(rdr: &mut StringReader,
                 rdr.fatal(~"unterminated block comment");
             }
             if rdr.curr_is('\n') {
-                trim_whitespace_prefix_and_push_line(&mut lines, curr_line,
+                trim_whitespace_prefix_and_push_line(&mut lines,
+                                                     curr_line.into_owned(),
                                                      col);
-                curr_line = ~"";
+                curr_line = StrBuf::new();
                 bump(rdr);
             } else {
                 curr_line.push_char(rdr.curr.unwrap());
@@ -301,7 +305,9 @@ fn read_block_comment(rdr: &mut StringReader,
             }
         }
         if curr_line.len() != 0 {
-            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(&mut lines,
+                                                 curr_line.into_owned(),
+                                                 col);
         }
     }
 
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 23d7cc0af97..c1c91cb6a4f 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -21,6 +21,7 @@ use std::mem::replace;
 use std::num::from_str_radix;
 use std::rc::Rc;
 use std::str;
+use std::strbuf::StrBuf;
 
 pub use ext::tt::transcribe::{TtReader, new_tt_reader};
 
@@ -152,10 +153,10 @@ fn fatal_span_char(rdr: &mut StringReader,
                    m: ~str,
                    c: char)
                 -> ! {
-    let mut m = m;
+    let mut m = StrBuf::from_owned_str(m);
     m.push_str(": ");
     char::escape_default(c, |c| m.push_char(c));
-    fatal_span(rdr, from_pos, to_pos, m);
+    fatal_span(rdr, from_pos, to_pos, m.into_owned());
 }
 
 // report a lexical error spanning [`from_pos`, `to_pos`), appending the
@@ -165,12 +166,12 @@ fn fatal_span_verbose(rdr: &mut StringReader,
                       to_pos: BytePos,
                       m: ~str)
                    -> ! {
-    let mut m = m;
+    let mut m = StrBuf::from_owned_str(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);
+    fatal_span(rdr, from_pos, to_pos, m.into_owned());
 }
 
 // EFFECT: advance peek_tok and peek_span to refer to the next token.
@@ -440,7 +441,7 @@ fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> {
 fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
     // \x00 hits the `return None` case immediately, so this is fine.
     let mut c = rdr.curr.unwrap_or('\x00');
-    let mut rslt = ~"";
+    let mut rslt = StrBuf::new();
     if c == 'e' || c == 'E' {
         rslt.push_char(c);
         bump(rdr);
@@ -451,7 +452,8 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
         }
         let exponent = scan_digits(rdr, 10u);
         if exponent.len() > 0u {
-            return Some(rslt + exponent);
+            rslt.push_str(exponent);
+            return Some(rslt.into_owned());
         } else {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"scan_exponent: bad fp literal");
@@ -460,7 +462,7 @@ fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> {
 }
 
 fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
-    let mut rslt = ~"";
+    let mut rslt = StrBuf::new();
     loop {
         let c = rdr.curr;
         if c == Some('_') { bump(rdr); continue; }
@@ -469,7 +471,7 @@ fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str {
             rslt.push_char(c.unwrap());
             bump(rdr);
           }
-          _ => return rslt
+          _ => return rslt.into_owned()
         }
     };
 }
@@ -506,7 +508,7 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
         bump(rdr);
         base = 2u;
     }
-    num_str = scan_digits(rdr, base);
+    num_str = StrBuf::from_owned_str(scan_digits(rdr, base));
     c = rdr.curr.unwrap_or('\x00');
     nextch(rdr);
     if c == 'u' || c == 'i' {
@@ -544,7 +546,8 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"no valid digits found for number");
         }
-        let parsed = match from_str_radix::<u64>(num_str, base as uint) {
+        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")
@@ -579,12 +582,14 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
             bump(rdr);
             bump(rdr);
             check_float_base(rdr, start_bpos, rdr.last_pos, base);
-            return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF32);
+            return token::LIT_FLOAT(str_to_ident(num_str.into_owned()),
+                                    ast::TyF32);
         } else if c == '6' && n == '4' {
             bump(rdr);
             bump(rdr);
             check_float_base(rdr, start_bpos, rdr.last_pos, base);
-            return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF64);
+            return token::LIT_FLOAT(str_to_ident(num_str.into_owned()),
+                                    ast::TyF64);
             /* FIXME (#2252): if this is out of range for either a
             32-bit or 64-bit float, it won't be noticed till the
             back-end.  */
@@ -595,19 +600,22 @@ fn scan_number(c: char, rdr: &mut StringReader) -> token::Token {
     }
     if is_float {
         check_float_base(rdr, start_bpos, rdr.last_pos, base);
-        return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(num_str));
+        return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(
+                num_str.into_owned()));
     } else {
         if num_str.len() == 0u {
             fatal_span(rdr, start_bpos, rdr.last_pos,
                        ~"no valid digits found for number");
         }
-        let parsed = match from_str_radix::<u64>(num_str, base as uint) {
+        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")
         };
 
-        debug!("lexing {} as an unsuffixed integer literal", num_str);
+        debug!("lexing {} as an unsuffixed integer literal",
+               num_str.as_slice());
         return token::LIT_INT_UNSUFFIXED(parsed as i64);
     }
 }
@@ -863,7 +871,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
         return token::LIT_CHAR(c2 as u32);
       }
       '"' => {
-        let mut accum_str = ~"";
+        let mut accum_str = StrBuf::new();
         let start_bpos = rdr.last_pos;
         bump(rdr);
         while !rdr.curr_is('"') {
@@ -912,7 +920,7 @@ fn next_token_inner(rdr: &mut StringReader) -> token::Token {
             }
         }
         bump(rdr);
-        return token::LIT_STR(str_to_ident(accum_str));
+        return token::LIT_STR(str_to_ident(accum_str.as_slice()));
       }
       'r' => {
         let start_bpos = rdr.last_pos;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe4bd87c4eb..6bc325bffcc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -79,6 +79,7 @@ use owned_slice::OwnedSlice;
 use collections::HashSet;
 use std::mem::replace;
 use std::rc::Rc;
+use std::strbuf::StrBuf;
 
 #[allow(non_camel_case_types)]
 #[deriving(Eq)]
@@ -4136,14 +4137,14 @@ impl<'a> Parser<'a> {
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
         match included_mod_stack.iter().position(|p| *p == path) {
             Some(i) => {
-                let mut err = ~"circular modules: ";
+                let mut err = StrBuf::from_str("circular modules: ");
                 let len = included_mod_stack.len();
                 for p in included_mod_stack.slice(i, len).iter() {
                     err.push_str(p.display().as_maybe_owned().as_slice());
                     err.push_str(" -> ");
                 }
                 err.push_str(path.display().as_maybe_owned().as_slice());
-                self.span_fatal(id_sp, err);
+                self.span_fatal(id_sp, err.into_owned());
             }
             None => ()
         }
@@ -4711,14 +4712,14 @@ impl<'a> Parser<'a> {
 
         // FAILURE TO PARSE ITEM
         if visibility != Inherited {
-            let mut s = ~"unmatched visibility `";
+            let mut s = StrBuf::from_str("unmatched visibility `");
             if visibility == Public {
                 s.push_str("pub")
             } else {
                 s.push_str("priv")
             }
             s.push_char('`');
-            self.span_fatal(self.last_span, s);
+            self.span_fatal(self.last_span, s.as_slice());
         }
         return IoviNone(attrs);
     }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index ff1509fe23a..baade21d942 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -23,6 +23,7 @@ use std::fmt;
 use std::local_data;
 use std::path::BytesContainer;
 use std::rc::Rc;
+use std::strbuf::StrBuf;
 
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash, Show)]
@@ -193,12 +194,12 @@ pub fn to_str(t: &Token) -> ~str {
 
       /* Literals */
       LIT_CHAR(c) => {
-          let mut res = ~"'";
+          let mut res = StrBuf::from_str("'");
           char::from_u32(c).unwrap().escape_default(|c| {
               res.push_char(c);
           });
           res.push_char('\'');
-          res
+          res.into_owned()
       }
       LIT_INT(i, t) => {
           i.to_str() + ast_util::int_ty_to_str(t)
@@ -208,18 +209,19 @@ pub fn to_str(t: &Token) -> ~str {
       }
       LIT_INT_UNSUFFIXED(i) => { i.to_str() }
       LIT_FLOAT(s, t) => {
-        let mut body = get_ident(s).get().to_str();
-        if body.ends_with(".") {
+        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 + ast_util::float_ty_to_str(t)
+        body.push_str(ast_util::float_ty_to_str(t));
+        body.into_owned()
       }
       LIT_FLOAT_UNSUFFIXED(s) => {
-        let mut body = get_ident(s).get().to_str();
-        if body.ends_with(".") {
+        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
+        body.into_owned()
       }
       LIT_STR(s) => {
           format!("\"{}\"", get_ident(s).get().escape_default())
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 7b64d0293cc..6cd72cb58f1 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -62,6 +62,7 @@
  */
 
 use std::io;
+use std::strbuf::StrBuf;
 
 #[deriving(Clone, Eq)]
 pub enum Breaks {
@@ -118,13 +119,17 @@ pub fn tok_str(t: Token) -> ~str {
     }
 }
 
-pub fn buf_str(toks: Vec<Token> , szs: Vec<int> , left: uint, right: uint,
-               lim: uint) -> ~str {
+pub fn buf_str(toks: Vec<Token>,
+               szs: Vec<int>,
+               left: uint,
+               right: uint,
+               lim: uint)
+               -> ~str {
     let n = toks.len();
     assert_eq!(n, szs.len());
     let mut i = left;
     let mut l = lim;
-    let mut s = ~"[";
+    let mut s = StrBuf::from_str("[");
     while i != right && l != 0u {
         l -= 1u;
         if i != left {
@@ -135,7 +140,7 @@ pub fn buf_str(toks: Vec<Token> , szs: Vec<int> , left: uint, right: uint,
         i %= n;
     }
     s.push_char(']');
-    return s;
+    return s.into_owned();
 }
 
 pub enum PrintStackBreak {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index b33f76a6047..3e2509f4f6e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -27,10 +27,11 @@ use print::pp;
 
 use std::cast;
 use std::char;
-use std::str;
-use std::io;
 use std::io::{IoResult, MemWriter};
+use std::io;
 use std::rc::Rc;
+use std::str;
+use std::strbuf::StrBuf;
 
 pub enum AnnNode<'a> {
     NodeBlock(&'a ast::Block),
@@ -2156,10 +2157,10 @@ impl<'a> State<'a> {
         match lit.node {
             ast::LitStr(ref st, style) => self.print_string(st.get(), style),
             ast::LitChar(ch) => {
-                let mut res = ~"'";
+                let mut res = StrBuf::from_str("'");
                 char::from_u32(ch).unwrap().escape_default(|c| res.push_char(c));
                 res.push_char('\'');
-                word(&mut self.s, res)
+                word(&mut self.s, res.into_owned())
             }
             ast::LitInt(i, t) => {
                 word(&mut self.s, format!("{}{}", i, ast_util::int_ty_to_str(t)))