about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-16 00:04:13 -0700
committerbors <bors@rust-lang.org>2013-06-16 00:04:13 -0700
commitf74e1935aa55aff7ecf9ac75a5114a7b41d4e56f (patch)
tree95cfabfbe2e63d3f42d0d8966d6b4af31ffb6c39
parent8482d29d9b27a00e2d84bbf3bc0a3d14c61e34ba (diff)
parentbbcff95ac51f5533866d307a85eedb062a1a05da (diff)
downloadrust-f74e1935aa55aff7ecf9ac75a5114a7b41d4e56f.tar.gz
rust-f74e1935aa55aff7ecf9ac75a5114a7b41d4e56f.zip
auto merge of #7123 : huonw/rust/more-str, r=thestinger
Moves all the remaining functions that could reasonably be methods to be methods, except for some FFI ones (which I believe @erickt is working on, possibly) and `each_split_within`, since I'm not really sure the details of it (I believe @kimundi wrote the current implementation, so maybe he could convert it to an external iterator method on `StrSlice`, e.g. `word_wrap_iter(&self) -> WordWrapIterator<'self>`, where `WordWrapIterator` impls `Iterator<&'self str>`. It probably won't be too hard, since it's already a state machine.)

This also cleans up the comparison impls for the string types, except I'm not sure how the lang items `eq_str` and `eq_str_uniq` need to be handled, so they (`eq_slice` and `eq`) remain stand-alone functions.
-rw-r--r--src/compiletest/runtest.rs1
-rw-r--r--src/libextra/base64.rs2
-rw-r--r--src/libextra/rope.rs1
-rw-r--r--src/libextra/sha1.rs3
-rw-r--r--src/libextra/smallintmap.rs5
-rw-r--r--src/libextra/sort.rs3
-rw-r--r--src/libextra/stats.rs1
-rw-r--r--src/libextra/std.rc1
-rw-r--r--src/libextra/tempfile.rs1
-rw-r--r--src/libextra/terminfo/parser/compiled.rs1
-rw-r--r--src/libextra/test.rs3
-rw-r--r--src/libextra/treemap.rs1
-rw-r--r--src/librustc/back/rpath.rs3
-rw-r--r--src/librustc/middle/astencode.rs1
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/trans/adt.rs1
-rw-r--r--src/librustc/middle/trans/base.rs2
-rw-r--r--src/librustdoc/astsrv.rs2
-rw-r--r--src/librustdoc/desc_to_brief_pass.rs17
-rw-r--r--src/librustdoc/extract.rs2
-rw-r--r--src/librustdoc/markdown_pass.rs7
-rw-r--r--src/librustdoc/page_pass.rs1
-rw-r--r--src/librustdoc/prune_hidden_pass.rs2
-rw-r--r--src/librustdoc/prune_private_pass.rs1
-rw-r--r--src/librustdoc/sectionalize_pass.rs27
-rw-r--r--src/librustdoc/text_pass.rs2
-rw-r--r--src/librustdoc/unindent_pass.rs31
-rw-r--r--src/librusti/rusti.rc2
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/path.rs13
-rw-r--r--src/libstd/str.rs613
-rw-r--r--src/libsyntax/ext/quote.rs2
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/parse/comments.rs14
34 files changed, 342 insertions, 430 deletions
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 891935dcadd..e0ceb79a37d 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -24,7 +24,6 @@ use util::logv;
 
 use core::io;
 use core::os;
-use core::str;
 use core::uint;
 use core::vec;
 
diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs
index f4754b3e4cb..5bf4dd517a5 100644
--- a/src/libextra/base64.rs
+++ b/src/libextra/base64.rs
@@ -229,8 +229,6 @@ impl<'self> FromBase64 for &'self str {
 
 #[cfg(test)]
 mod tests {
-    use core::str;
-
     #[test]
     fn test_to_base64() {
         assert_eq!("".to_base64(), ~"");
diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs
index 12539cd4759..fed73256c00 100644
--- a/src/libextra/rope.rs
+++ b/src/libextra/rope.rs
@@ -1271,7 +1271,6 @@ mod tests {
 
     use rope::*;
 
-    use core::str;
     use core::uint;
     use core::vec;
 
diff --git a/src/libextra/sha1.rs b/src/libextra/sha1.rs
index 0c35630345b..7c4b3f4ce39 100644
--- a/src/libextra/sha1.rs
+++ b/src/libextra/sha1.rs
@@ -24,7 +24,6 @@
 
 use core::prelude::*;
 
-use core::str;
 use core::uint;
 use core::vec;
 
@@ -279,8 +278,6 @@ pub fn sha1() -> @Sha1 {
 mod tests {
     use sha1;
 
-    use core::vec;
-
     #[test]
     fn test() {
         struct Test {
diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs
index dae9113b3a9..972bccde18a 100644
--- a/src/libextra/smallintmap.rs
+++ b/src/libextra/smallintmap.rs
@@ -294,11 +294,6 @@ mod tests {
 
     use super::SmallIntMap;
 
-    use core::local_data;
-    use core::rand;
-    use core::uint;
-    use core::vec;
-
     #[test]
     fn test_find_mut() {
         let mut m = SmallIntMap::new();
diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs
index 0189e0db6d4..b88fd374da2 100644
--- a/src/libextra/sort.rs
+++ b/src/libextra/sort.rs
@@ -751,7 +751,6 @@ fn shift_vec<T:Copy>(dest: &mut [T],
 mod test_qsort3 {
     use sort::*;
 
-    use core::vec;
 
     fn check_sort(v1: &mut [int], v2: &mut [int]) {
         let len = v1.len();
@@ -861,8 +860,6 @@ mod tests {
 
     use sort::*;
 
-    use core::vec;
-
     fn check_sort(v1: &[int], v2: &[int]) {
         let len = v1.len();
         pub fn le(a: &int, b: &int) -> bool { *a <= *b }
diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs
index 4af47fa806f..3a1de5de01d 100644
--- a/src/libextra/stats.rs
+++ b/src/libextra/stats.rs
@@ -12,7 +12,6 @@
 
 use core::prelude::*;
 
-use core::vec;
 use core::f64;
 use core::cmp;
 use core::num;
diff --git a/src/libextra/std.rc b/src/libextra/std.rc
index 83c0bb516b4..93759bea35f 100644
--- a/src/libextra/std.rc
+++ b/src/libextra/std.rc
@@ -37,6 +37,7 @@ not required in or otherwise suitable for the core library.
 
 extern mod core(name = "std", vers = "0.7-pre");
 
+#[cfg(stage0)]
 use core::{str, unstable};
 use core::str::{StrSlice, OwnedStr};
 
diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs
index c239e65e2d9..39dcee5eff3 100644
--- a/src/libextra/tempfile.rs
+++ b/src/libextra/tempfile.rs
@@ -36,7 +36,6 @@ mod tests {
     use tempfile::mkdtemp;
 
     use core::os;
-    use core::str;
 
     #[test]
     fn test_mkdtemp() {
diff --git a/src/libextra/terminfo/parser/compiled.rs b/src/libextra/terminfo/parser/compiled.rs
index 81b6083db01..66649c62fca 100644
--- a/src/libextra/terminfo/parser/compiled.rs
+++ b/src/libextra/terminfo/parser/compiled.rs
@@ -313,7 +313,6 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
 #[cfg(test)]
 mod test {
     use super::*;
-    use p = core::path::Path;
 
     #[test]
     fn test_veclens() {
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index a465cef09e6..72837cb4ae1 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -26,7 +26,6 @@ use core::either;
 use core::io;
 use core::option;
 use core::result;
-use core::str;
 use core::task;
 use core::to_str::ToStr;
 use core::uint;
@@ -542,7 +541,7 @@ pub fn filter_tests(
 
     // Sort the tests alphabetically
     fn lteq(t1: &TestDescAndFn, t2: &TestDescAndFn) -> bool {
-        str::le(t1.desc.name.to_str(), t2.desc.name.to_str())
+        t1.desc.name.to_str() < t2.desc.name.to_str()
     }
     sort::quick_sort(filtered, lteq);
 
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index f98758f64af..e37ce7c71ef 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -710,7 +710,6 @@ mod test_treemap {
 
     use core::rand::RngUtil;
     use core::rand;
-    use core::str;
     use core::vec;
 
     #[test]
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
index 85fc0575170..33f578d335b 100644
--- a/src/librustc/back/rpath.rs
+++ b/src/librustc/back/rpath.rs
@@ -199,9 +199,6 @@ pub fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
 mod test {
     use core::prelude::*;
 
-    use core::os;
-    use core::str;
-
     // FIXME(#2119): the outer attribute should be #[cfg(unix, test)], then
     // these redundant #[cfg(test)] blocks can be removed
     #[cfg(test)]
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index e11367a7a7d..925b1f506d7 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -15,7 +15,6 @@ use cstore = metadata::cstore;
 use driver::session::Session;
 use e = metadata::encoder;
 use metadata::decoder;
-use metadata::encoder;
 use metadata::tydecode;
 use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter};
 use metadata::tyencode;
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 2803608567d..3e656b3e594 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -4845,7 +4845,7 @@ impl Resolver {
         let mut smallest = 0;
         for maybes.eachi |i, &other| {
 
-            values[i] = str::levdistance(name, other);
+            values[i] = name.lev_distance(other);
 
             if values[i] <= values[smallest] {
                 smallest = i;
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index 9ae241c7030..5481ed9a7fd 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -47,7 +47,6 @@
 use core::container::Map;
 use core::libc::c_ulonglong;
 use core::option::{Option, Some, None};
-use core::str;
 use core::vec;
 
 use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE};
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index e2073d21fe3..ffc54bbed35 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -71,7 +71,6 @@ use core::libc::c_uint;
 use core::str;
 use core::uint;
 use core::vec;
-use core::local_data;
 use extra::time;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt_to_str, path_name};
@@ -3120,4 +3119,3 @@ pub fn trans_crate(sess: session::Session,
 
     return (llcx, llmod, link_meta);
 }
-
diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs
index 9d8f750a350..3775aafb569 100644
--- a/src/librustdoc/astsrv.rs
+++ b/src/librustdoc/astsrv.rs
@@ -32,8 +32,6 @@ use syntax::ast;
 use syntax::ast_map;
 use syntax;
 
-#[cfg(test)] use core::vec;
-
 pub struct Ctxt {
     ast: @ast::crate,
     ast_map: ast_map::map
diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs
index 51fea9b46b3..dbaa5e8532c 100644
--- a/src/librustdoc/desc_to_brief_pass.rs
+++ b/src/librustdoc/desc_to_brief_pass.rs
@@ -24,7 +24,6 @@ use fold::Fold;
 use fold;
 use pass::Pass;
 
-use core::str;
 use core::util;
 
 pub fn mk_pass() -> Pass {
@@ -129,25 +128,21 @@ fn first_sentence_(s: &str) -> ~str {
         }
     });
     match idx {
-        Some(idx) if idx > 2u => {
-            str::to_owned(s.slice(0, idx - 1))
-        }
+        Some(idx) if idx > 2u => s.slice(0, idx - 1).to_owned(),
         _ => {
             if s.ends_with(".") {
-                str::to_owned(s)
+                s.to_owned()
             } else {
-                str::to_owned(s)
+                s.to_owned()
             }
         }
     }
 }
 
 pub fn paragraphs(s: &str) -> ~[~str] {
-    let mut lines = ~[];
-    for str::each_line_any(s) |line| { lines.push(line.to_owned()); }
     let mut whitespace_lines = 0;
     let mut accum = ~"";
-    let paras = do lines.iter().fold(~[]) |paras, line| {
+    let paras = do s.any_line_iter().fold(~[]) |paras, line| {
         let mut res = paras;
 
         if line.is_whitespace() {
@@ -163,9 +158,9 @@ pub fn paragraphs(s: &str) -> ~[~str] {
             whitespace_lines = 0;
 
             accum = if accum.is_empty() {
-                copy *line
+                line.to_owned()
             } else {
-                accum + "\n" + *line
+                fmt!("%s\n%s", accum, line)
             }
         }
 
diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs
index f4b6ae8fb32..f8c49f544bc 100644
--- a/src/librustdoc/extract.rs
+++ b/src/librustdoc/extract.rs
@@ -285,8 +285,6 @@ mod test {
     use extract::{extract, from_srv};
     use parse;
 
-    use core::vec;
-
     fn mk_doc(source: @str) -> doc::Doc {
         let ast = parse::from_str(source);
         extract(ast, ~"")
diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs
index 17db7c24a7c..075b64a674c 100644
--- a/src/librustdoc/markdown_pass.rs
+++ b/src/librustdoc/markdown_pass.rs
@@ -466,10 +466,7 @@ fn write_variant(ctxt: &Ctxt, doc: doc::VariantDoc) {
 }
 
 fn list_item_indent(item: &str) -> ~str {
-    let mut indented = ~[];
-    for str::each_line_any(item) |line| {
-        indented.push(line);
-    }
+    let indented = item.any_line_iter().collect::<~[&str]>();
 
     // separate markdown elements within `*` lists must be indented by four
     // spaces, or they will escape the list context. indenting everything
@@ -539,8 +536,6 @@ mod test {
     use tystr_pass;
     use unindent_pass;
 
-    use core::str;
-
     fn render(source: ~str) -> ~str {
         let (srv, doc) = create_doc_srv(source);
         let markdown = write_markdown_str_srv(srv, doc);
diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs
index bb5d71e8db1..584e6ccc887 100644
--- a/src/librustdoc/page_pass.rs
+++ b/src/librustdoc/page_pass.rs
@@ -157,7 +157,6 @@ mod test {
     use doc;
     use extract;
     use page_pass::run;
-    use core::vec;
 
     fn mk_doc_(
         output_style: config::OutputStyle,
diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs
index 8a90d3f74d3..484eb8c7980 100644
--- a/src/librustdoc/prune_hidden_pass.rs
+++ b/src/librustdoc/prune_hidden_pass.rs
@@ -77,8 +77,6 @@ mod test {
 
     #[test]
     fn should_prune_hidden_items() {
-        use core::vec;
-
         let doc = mk_doc(~"#[doc(hidden)] mod a { }");
         assert!(doc.cratemod().mods().is_empty())
     }
diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs
index e861939c2dd..741da3e265e 100644
--- a/src/librustdoc/prune_private_pass.rs
+++ b/src/librustdoc/prune_private_pass.rs
@@ -162,7 +162,6 @@ mod test {
     use extract;
     use tystr_pass;
     use prune_private_pass::run;
-    use core::vec;
 
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs
index 8716f823848..ba433bf479d 100644
--- a/src/librustdoc/sectionalize_pass.rs
+++ b/src/librustdoc/sectionalize_pass.rs
@@ -19,7 +19,7 @@ use fold::Fold;
 use fold;
 use pass::Pass;
 
-use core::str;
+use core::iterator::IteratorUtil;
 
 pub fn mk_pass() -> Pass {
     Pass {
@@ -104,21 +104,19 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
     if desc.is_none() {
         return (None, ~[]);
     }
-    let mut lines = ~[];
-    for str::each_line_any(*desc.get_ref()) |line| { lines.push(line.to_owned()); }
 
     let mut new_desc = None::<~str>;
     let mut current_section = None;
     let mut sections = ~[];
 
-    for lines.each |line| {
-        match parse_header(copy *line) {
+    for desc.get_ref().any_line_iter().advance |line| {
+        match parse_header(line) {
           Some(header) => {
             if current_section.is_some() {
-                sections += [copy *current_section.get_ref()];
+                sections.push(copy *current_section.get_ref());
             }
             current_section = Some(doc::Section {
-                header: header,
+                header: header.to_owned(),
                 body: ~""
             });
           }
@@ -126,17 +124,17 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
             match copy current_section {
               Some(section) => {
                 current_section = Some(doc::Section {
-                    body: section.body + "\n" + *line,
+                    body: fmt!("%s\n%s", section.body, line),
                     .. section
                 });
               }
               None => {
                 new_desc = match copy new_desc {
                   Some(desc) => {
-                    Some(desc + "\n" + *line)
+                    Some(fmt!("%s\n%s", desc, line))
                   }
                   None => {
-                    Some(copy *line)
+                    Some(line.to_owned())
                   }
                 };
               }
@@ -146,15 +144,15 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
     }
 
     if current_section.is_some() {
-        sections += [current_section.get()];
+        sections.push(current_section.unwrap());
     }
 
     (new_desc, sections)
 }
 
-fn parse_header(line: ~str) -> Option<~str> {
+fn parse_header<'a>(line: &'a str) -> Option<&'a str> {
     if line.starts_with("# ") {
-        Some(line.slice(2u, line.len()).to_owned())
+        Some(line.slice_from(2))
     } else {
         None
     }
@@ -172,9 +170,6 @@ mod test {
     use extract;
     use sectionalize_pass::run;
 
-    use core::str;
-    use core::vec;
-
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
             let doc = extract::from_srv(srv.clone(), ~"");
diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs
index 1f7a71e0fd8..6db582a60e9 100644
--- a/src/librustdoc/text_pass.rs
+++ b/src/librustdoc/text_pass.rs
@@ -149,8 +149,6 @@ mod test {
     use sectionalize_pass;
     use text_pass::mk_pass;
 
-    use core::str;
-
     fn mk_doc(source: ~str) -> doc::Doc {
         do astsrv::from_str(copy source) |srv| {
             let doc = extract::from_srv(srv.clone(), ~"");
diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs
index caf0e5376d1..2bcf04c0262 100644
--- a/src/librustdoc/unindent_pass.rs
+++ b/src/librustdoc/unindent_pass.rs
@@ -21,7 +21,6 @@ middle of a line, and each of the following lines is indented.
 
 use core::prelude::*;
 
-use core::str;
 use core::uint;
 use pass::Pass;
 use text_pass;
@@ -31,8 +30,7 @@ pub fn mk_pass() -> Pass {
 }
 
 fn unindent(s: &str) -> ~str {
-    let mut lines = ~[];
-    for str::each_line_any(s) |line| { lines.push(line.to_owned()); }
+    let lines = s.any_line_iter().collect::<~[&str]>();
     let mut saw_first_line = false;
     let mut saw_second_line = false;
     let min_indent = do lines.iter().fold(uint::max_value)
@@ -76,19 +74,20 @@ fn unindent(s: &str) -> ~str {
         }
     };
 
-    if !lines.is_empty() {
-        let unindented = ~[lines.head().trim().to_owned()]
-            + do lines.tail().map |line| {
-            if line.is_whitespace() {
-                copy *line
-            } else {
-                assert!(line.len() >= min_indent);
-                line.slice(min_indent, line.len()).to_owned()
-            }
-        };
-        unindented.connect("\n")
-    } else {
-        s.to_str()
+    match lines {
+        [head, .. tail] => {
+            let mut unindented = ~[ head.trim() ];
+            unindented.push_all(do tail.map |&line| {
+                if line.is_whitespace() {
+                    line
+                } else {
+                    assert!(line.len() >= min_indent);
+                    line.slice_from(min_indent)
+                }
+            });
+            unindented.connect("\n")
+        }
+        [] => s.to_owned()
     }
 }
 
diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc
index 06ec6769385..0af6ed724e1 100644
--- a/src/librusti/rusti.rc
+++ b/src/librusti/rusti.rc
@@ -370,7 +370,7 @@ fn run_cmd(repl: &mut Repl, _in: @io::Reader, _out: @io::Writer,
                     if arg.ends_with(".rs") || arg.ends_with(".rc") {
                     (arg.slice_to(arg.len() - 3).to_owned(), copy *arg)
                 } else {
-                    (copy *arg, arg + ".rs")
+                    (copy *arg, *arg + ".rs")
                 };
                 match compile_crate(filename, copy repl.binary) {
                     Some(_) => loaded_crates.push(crate),
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index fffcb34dc09..e48dc723c47 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -144,7 +144,7 @@ pub mod win32 {
     }
 
     pub fn as_utf16_p<T>(s: &str, f: &fn(*u16) -> T) -> T {
-        let mut t = str::to_utf16(s);
+        let mut t = s.to_utf16();
         // Null terminate before passing on.
         t += [0u16];
         vec::as_imm_buf(t, |buf, _len| f(buf))
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 400657d0c25..9c4e8f08358 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -515,7 +515,7 @@ impl GenericPath for PosixPath {
     fn with_filestem(&self, s: &str) -> PosixPath {
         match self.filetype() {
             None => self.with_filename(s),
-            Some(ref t) => self.with_filename(str::to_owned(s) + *t),
+            Some(ref t) => self.with_filename(s.to_owned() + *t),
         }
     }
 
@@ -657,7 +657,7 @@ impl GenericPath for WindowsPath {
             (None, None) => {
                 host = None;
                 device = None;
-                rest = str::to_owned(s);
+                rest = s.to_owned();
             }
         }
 
@@ -729,7 +729,7 @@ impl GenericPath for WindowsPath {
     fn with_filestem(&self, s: &str) -> WindowsPath {
         match self.filetype() {
             None => self.with_filename(s),
-            Some(ref t) => self.with_filename(str::to_owned(s) + *t),
+            Some(ref t) => self.with_filename(s.to_owned() + *t),
         }
     }
 
@@ -947,7 +947,6 @@ pub mod windows {
 mod tests {
     use option::{None, Some};
     use path::{PosixPath, WindowsPath, windows};
-    use str;
 
     #[test]
     fn test_double_slash_collapsing() {
@@ -984,7 +983,7 @@ mod tests {
     fn test_posix_paths() {
         fn t(wp: &PosixPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
@@ -1042,7 +1041,7 @@ mod tests {
     fn test_normalize() {
         fn t(wp: &PosixPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
@@ -1105,7 +1104,7 @@ mod tests {
     fn test_windows_paths() {
         fn t(wp: &WindowsPath, s: &str) {
             let ss = wp.to_str();
-            let sss = str::to_owned(s);
+            let sss = s.to_owned();
             if (ss != sss) {
                 debug!("got %s", ss);
                 debug!("expected %s", sss);
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 1086fcaa75c..21f747317f4 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -23,10 +23,9 @@ use cast;
 use char;
 use char::Char;
 use clone::Clone;
-use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
 use container::Container;
 use iter::Times;
-use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator};
+use iterator::{Iterator, IteratorUtil, FilterIterator, AdditiveIterator, MapIterator};
 use libc;
 use option::{None, Option, Some};
 use old_iter::{BaseIter, EqIter};
@@ -37,8 +36,6 @@ use uint;
 use vec;
 use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector};
 
-#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
-
 /*
 Section: Conditions
 */
@@ -291,6 +288,10 @@ pub type WordIterator<'self> =
     FilterIterator<'self, &'self str,
              StrCharSplitIterator<'self, extern "Rust" fn(char) -> bool>>;
 
+/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
+pub type AnyLineIterator<'self> =
+    MapIterator<'self, &'self str, &'self str, StrCharSplitIterator<'self, char>>;
+
 impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Sep> {
     #[inline]
     fn next(&mut self) -> Option<&'self str> {
@@ -400,56 +401,6 @@ impl<'self> Iterator<&'self str> for StrStrSplitIterator<'self> {
     }
 }
 
-/// Levenshtein Distance between two strings
-pub fn levdistance(s: &str, t: &str) -> uint {
-
-    let slen = s.len();
-    let tlen = t.len();
-
-    if slen == 0 { return tlen; }
-    if tlen == 0 { return slen; }
-
-    let mut dcol = vec::from_fn(tlen + 1, |x| x);
-
-    for s.iter().enumerate().advance |(i, sc)| {
-
-        let mut current = i;
-        dcol[0] = current + 1;
-
-        for t.iter().enumerate().advance |(j, tc)| {
-
-            let next = dcol[j + 1];
-
-            if sc == tc {
-                dcol[j + 1] = current;
-            } else {
-                dcol[j + 1] = ::cmp::min(current, next);
-                dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
-            }
-
-            current = next;
-        }
-    }
-
-    return dcol[tlen];
-}
-
-/**
- * Splits a string into substrings separated by LF ('\n')
- * and/or CR LF ("\r\n")
- */
-pub fn each_line_any<'a>(s: &'a str, it: &fn(&'a str) -> bool) -> bool {
-    for s.line_iter().advance |s| {
-        let l = s.len();
-        if l > 0u && s[l - 1u] == '\r' as u8 {
-            if !it( unsafe { raw::slice_bytes(s, 0, l - 1) } ) { return false; }
-        } else {
-            if !it( s ) { return false; }
-        }
-    }
-    return true;
-}
-
 /** Splits a string into substrings with possibly internal whitespace,
  *  each of them at most `lim` bytes long. The substrings have leading and trailing
  *  whitespace removed, and are only cut at whitespace boundaries.
@@ -576,196 +527,6 @@ pub fn eq(a: &~str, b: &~str) -> bool {
     eq_slice(*a, *b)
 }
 
-#[inline]
-fn cmp(a: &str, b: &str) -> Ordering {
-    let low = uint::min(a.len(), b.len());
-
-    for uint::range(0, low) |idx| {
-        match a[idx].cmp(&b[idx]) {
-          Greater => return Greater,
-          Less => return Less,
-          Equal => ()
-        }
-    }
-
-    a.len().cmp(&b.len())
-}
-
-#[cfg(not(test))]
-impl<'self> TotalOrd for &'self str {
-    #[inline]
-    fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for ~str {
-    #[inline]
-    fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) }
-}
-
-#[cfg(not(test))]
-impl TotalOrd for @str {
-    #[inline]
-    fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) }
-}
-
-/// Bytewise slice less than
-#[inline]
-fn lt(a: &str, b: &str) -> bool {
-    let (a_len, b_len) = (a.len(), b.len());
-    let end = uint::min(a_len, b_len);
-
-    let mut i = 0;
-    while i < end {
-        let (c_a, c_b) = (a[i], b[i]);
-        if c_a < c_b { return true; }
-        if c_a > c_b { return false; }
-        i += 1;
-    }
-
-    return a_len < b_len;
-}
-
-/// Bytewise less than or equal
-#[inline]
-pub fn le(a: &str, b: &str) -> bool {
-    !lt(b, a)
-}
-
-/// Bytewise greater than or equal
-#[inline]
-fn ge(a: &str, b: &str) -> bool {
-    !lt(a, b)
-}
-
-/// Bytewise greater than
-#[inline]
-fn gt(a: &str, b: &str) -> bool {
-    !le(a, b)
-}
-
-#[cfg(not(test))]
-impl<'self> Eq for &'self str {
-    #[inline(always)]
-    fn eq(&self, other: & &'self str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl Eq for ~str {
-    #[inline(always)]
-    fn eq(&self, other: &~str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl Eq for @str {
-    #[inline(always)]
-    fn eq(&self, other: &@str) -> bool {
-        eq_slice((*self), (*other))
-    }
-    #[inline(always)]
-    fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
-}
-
-#[cfg(not(test))]
-impl<'self> TotalEq for &'self str {
-    #[inline(always)]
-    fn equals(&self, other: & &'self str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl TotalEq for ~str {
-    #[inline(always)]
-    fn equals(&self, other: &~str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl TotalEq for @str {
-    #[inline(always)]
-    fn equals(&self, other: &@str) -> bool {
-        eq_slice((*self), (*other))
-    }
-}
-
-#[cfg(not(test))]
-impl Ord for ~str {
-    #[inline(always)]
-    fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: &~str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: &~str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl<'self> Ord for &'self str {
-    #[inline(always)]
-    fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: & &'self str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: & &'self str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl Ord for @str {
-    #[inline(always)]
-    fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) }
-    #[inline(always)]
-    fn le(&self, other: &@str) -> bool { le((*self), (*other)) }
-    #[inline(always)]
-    fn ge(&self, other: &@str) -> bool { ge((*self), (*other)) }
-    #[inline(always)]
-    fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) }
-}
-
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for &'self str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for @str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-
-#[cfg(not(test))]
-impl<'self, S: Str> Equiv<S> for ~str {
-    #[inline(always)]
-    fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
-}
-
-
-/*
-Section: Iterating through strings
-*/
-
-/// Apply a function to each character
-pub fn map(ss: &str, ff: &fn(char) -> char) -> ~str {
-    let mut result = ~"";
-    result.reserve(ss.len());
-    for ss.iter().advance |cc| {
-        result.push_char(ff(cc));
-    }
-    result
-}
-
 /*
 Section: Searching
 */
@@ -820,30 +581,6 @@ pub fn is_utf16(v: &[u16]) -> bool {
     return true;
 }
 
-/// Converts to a vector of `u16` encoded as UTF-16
-pub fn to_utf16(s: &str) -> ~[u16] {
-    let mut u = ~[];
-    for s.iter().advance |ch| {
-        // Arithmetic with u32 literals is easier on the eyes than chars.
-        let mut ch = ch as u32;
-
-        if (ch & 0xFFFF_u32) == ch {
-            // The BMP falls through (assuming non-surrogate, as it
-            // should)
-            assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
-            u.push(ch as u16)
-        } else {
-            // Supplementary planes break into surrogates.
-            assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
-            ch -= 0x1_0000_u32;
-            let w1 = 0xD800_u16 | ((ch >> 10) as u16);
-            let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
-            u.push_all([w1, w2])
-        }
-    }
-    u
-}
-
 /// Iterates over the utf-16 characters in the specified slice, yielding each
 /// decoded unicode character to the function provided.
 ///
@@ -989,40 +726,6 @@ pub fn as_buf<T>(s: &str, f: &fn(*u8, uint) -> T) -> T {
     }
 }
 
-/**
- * Returns the byte offset of an inner slice relative to an enclosing outer slice
- *
- * # Example
- *
- * ~~~ {.rust}
- * let string = "a\nb\nc";
- * let mut lines = ~[];
- * for string.line_iter().advance |line| { lines.push(line) }
- *
- * assert!(subslice_offset(string, lines[0]) == 0); // &"a"
- * assert!(subslice_offset(string, lines[1]) == 2); // &"b"
- * assert!(subslice_offset(string, lines[2]) == 4); // &"c"
- * ~~~
- */
-#[inline(always)]
-pub fn subslice_offset(outer: &str, inner: &str) -> uint {
-    do as_buf(outer) |a, a_len| {
-        do as_buf(inner) |b, b_len| {
-            let a_start: uint;
-            let a_end: uint;
-            let b_start: uint;
-            let b_end: uint;
-            unsafe {
-                a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
-                b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
-            }
-            assert!(a_start <= b_start);
-            assert!(b_end <= a_end);
-            b_start - a_start
-        }
-    }
-}
-
 /// Unsafe operations
 pub mod raw {
     use cast;
@@ -1207,12 +910,138 @@ pub mod raw {
 #[cfg(not(test))]
 pub mod traits {
     use ops::Add;
-    impl<'self> Add<&'self str,~str> for ~str {
+    use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
+    use super::{Str, eq_slice};
+
+    impl<'self> Add<&'self str,~str> for &'self str {
         #[inline(always)]
         fn add(&self, rhs: & &'self str) -> ~str {
-            self.append((*rhs))
+            let mut ret = self.to_owned();
+            ret.push_str(*rhs);
+            ret
         }
     }
+
+    impl<'self> TotalOrd for &'self str {
+        #[inline]
+        fn cmp(&self, other: & &'self str) -> Ordering {
+            for self.bytes_iter().zip(other.bytes_iter()).advance |(s_b, o_b)| {
+                match s_b.cmp(&o_b) {
+                    Greater => return Greater,
+                    Less => return Less,
+                    Equal => ()
+                }
+            }
+
+            self.len().cmp(&other.len())
+        }
+    }
+
+    impl TotalOrd for ~str {
+        #[inline]
+        fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
+
+    impl TotalOrd for @str {
+        #[inline]
+        fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
+
+    impl<'self> Eq for &'self str {
+        #[inline(always)]
+        fn eq(&self, other: & &'self str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline(always)]
+        fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
+    }
+
+    impl Eq for ~str {
+        #[inline(always)]
+        fn eq(&self, other: &~str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline(always)]
+        fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
+    }
+
+    impl Eq for @str {
+        #[inline(always)]
+        fn eq(&self, other: &@str) -> bool {
+            eq_slice((*self), (*other))
+        }
+        #[inline(always)]
+        fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
+    }
+
+    impl<'self> TotalEq for &'self str {
+        #[inline(always)]
+        fn equals(&self, other: & &'self str) -> bool {
+            eq_slice((*self), (*other))
+        }
+    }
+
+    impl TotalEq for ~str {
+        #[inline(always)]
+        fn equals(&self, other: &~str) -> bool {
+            eq_slice((*self), (*other))
+        }
+    }
+
+    impl TotalEq for @str {
+        #[inline(always)]
+        fn equals(&self, other: &@str) -> bool {
+            eq_slice((*self), (*other))
+        }
+    }
+
+    impl<'self> Ord for &'self str {
+        #[inline(always)]
+        fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less }
+        #[inline(always)]
+        fn le(&self, other: & &'self str) -> bool { self.cmp(other) != Greater }
+        #[inline(always)]
+        fn ge(&self, other: & &'self str) -> bool { self.cmp(other) != Less }
+        #[inline(always)]
+        fn gt(&self, other: & &'self str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl Ord for ~str {
+        #[inline(always)]
+        fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less }
+        #[inline(always)]
+        fn le(&self, other: &~str) -> bool { self.cmp(other) != Greater }
+        #[inline(always)]
+        fn ge(&self, other: &~str) -> bool { self.cmp(other) != Less }
+        #[inline(always)]
+        fn gt(&self, other: &~str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl Ord for @str {
+        #[inline(always)]
+        fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less }
+        #[inline(always)]
+        fn le(&self, other: &@str) -> bool { self.cmp(other) != Greater }
+        #[inline(always)]
+        fn ge(&self, other: &@str) -> bool { self.cmp(other) != Less }
+        #[inline(always)]
+        fn gt(&self, other: &@str) -> bool { self.cmp(other) == Greater }
+    }
+
+    impl<'self, S: Str> Equiv<S> for &'self str {
+        #[inline(always)]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
+
+    impl<'self, S: Str> Equiv<S> for @str {
+        #[inline(always)]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
+
+    impl<'self, S: Str> Equiv<S> for ~str {
+        #[inline(always)]
+        fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
+    }
 }
 
 #[cfg(test)]
@@ -1256,6 +1085,7 @@ pub trait StrSlice<'self> {
     fn matches_index_iter(&self, sep: &'self str) -> StrMatchesIndexIterator<'self>;
     fn split_str_iter(&self, &'self str) -> StrStrSplitIterator<'self>;
     fn line_iter(&self) -> StrCharSplitIterator<'self, char>;
+    fn any_line_iter(&self) -> AnyLineIterator<'self>;
     fn word_iter(&self) -> WordIterator<'self>;
     fn ends_with(&self, needle: &str) -> bool;
     fn is_empty(&self) -> bool;
@@ -1282,6 +1112,7 @@ pub trait StrSlice<'self> {
     fn replace(&self, from: &str, to: &str) -> ~str;
     fn to_owned(&self) -> ~str;
     fn to_managed(&self) -> @str;
+    fn to_utf16(&self) -> ~[u16];
     fn is_char_boundary(&self, index: uint) -> bool;
     fn char_range_at(&self, start: uint) -> CharRange;
     fn char_at(&self, i: uint) -> char;
@@ -1296,6 +1127,12 @@ pub trait StrSlice<'self> {
     fn repeat(&self, nn: uint) -> ~str;
 
     fn slice_shift_char(&self) -> (char, &'self str);
+
+    fn map_chars(&self, ff: &fn(char) -> char) -> ~str;
+
+    fn lev_distance(&self, t: &str) -> uint;
+
+    fn subslice_offset(&self, inner: &str) -> uint;
 }
 
 /// Extension methods for strings
@@ -1437,6 +1274,17 @@ impl<'self> StrSlice<'self> for &'self str {
     fn line_iter(&self) -> StrCharSplitIterator<'self, char> {
         self.split_options_iter('\n', self.len(), false)
     }
+
+    /// An iterator over the lines of a string, separated by either
+    /// `\n` or (`\r\n`).
+    fn any_line_iter(&self) -> AnyLineIterator<'self> {
+        do self.line_iter().transform |line| {
+            let l = line.len();
+            if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
+            else { line }
+        }
+    }
+
     /// An iterator over the words of a string (subsequences separated
     /// by any sequence of whitespace).
     #[inline]
@@ -1586,7 +1434,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
      * assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
      * assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
@@ -1605,7 +1453,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
      * assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
      * assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
@@ -1627,7 +1475,7 @@ impl<'self> StrSlice<'self> for &'self str {
      *
      * # Example
      *
-     * ~~~
+     * ~~~ {.rust}
      * assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
      * assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
      * assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
@@ -1679,6 +1527,30 @@ impl<'self> StrSlice<'self> for &'self str {
         unsafe { ::cast::transmute(v) }
     }
 
+    /// Converts to a vector of `u16` encoded as UTF-16.
+    fn to_utf16(&self) -> ~[u16] {
+        let mut u = ~[];
+        for self.iter().advance |ch| {
+            // Arithmetic with u32 literals is easier on the eyes than chars.
+            let mut ch = ch as u32;
+
+            if (ch & 0xFFFF_u32) == ch {
+                // The BMP falls through (assuming non-surrogate, as it
+                // should)
+                assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
+                u.push(ch as u16)
+            } else {
+                // Supplementary planes break into surrogates.
+                assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
+                ch -= 0x1_0000_u32;
+                let w1 = 0xD800_u16 | ((ch >> 10) as u16);
+                let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
+                u.push_all([w1, w2])
+            }
+        }
+        u
+    }
+
     /**
      * Returns false if the index points into the middle of a multi-byte
      * character sequence.
@@ -1921,6 +1793,85 @@ impl<'self> StrSlice<'self> for &'self str {
     }
 
 
+    /// Apply a function to each character.
+    fn map_chars(&self, ff: &fn(char) -> char) -> ~str {
+        let mut result = with_capacity(self.len());
+        for self.iter().advance |cc| {
+            result.push_char(ff(cc));
+        }
+        result
+    }
+
+    /// Levenshtein Distance between two strings.
+    fn lev_distance(&self, t: &str) -> uint {
+        let slen = self.len();
+        let tlen = t.len();
+
+        if slen == 0 { return tlen; }
+        if tlen == 0 { return slen; }
+
+        let mut dcol = vec::from_fn(tlen + 1, |x| x);
+
+        for self.iter().enumerate().advance |(i, sc)| {
+
+            let mut current = i;
+            dcol[0] = current + 1;
+
+            for t.iter().enumerate().advance |(j, tc)| {
+
+                let next = dcol[j + 1];
+
+                if sc == tc {
+                    dcol[j + 1] = current;
+                } else {
+                    dcol[j + 1] = ::cmp::min(current, next);
+                    dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
+                }
+
+                current = next;
+            }
+        }
+
+        return dcol[tlen];
+    }
+
+
+    /**
+     * Returns the byte offset of an inner slice relative to an enclosing outer slice.
+     *
+     * Fails if `inner` is not a direct slice contained within self.
+     *
+     * # Example
+     *
+     * ~~~ {.rust}
+     * let string = "a\nb\nc";
+     * let mut lines = ~[];
+     * for string.line_iter().advance |line| { lines.push(line) }
+     *
+     * assert!(string.subslice_offset(lines[0]) == 0); // &"a"
+     * assert!(string.subslice_offset(lines[1]) == 2); // &"b"
+     * assert!(string.subslice_offset(lines[2]) == 4); // &"c"
+     * ~~~
+     */
+    #[inline(always)]
+    fn subslice_offset(&self, inner: &str) -> uint {
+        do as_buf(*self) |a, a_len| {
+            do as_buf(inner) |b, b_len| {
+                let a_start: uint;
+                let a_end: uint;
+                let b_start: uint;
+                let b_end: uint;
+                unsafe {
+                    a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
+                    b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
+                }
+                assert!(a_start <= b_start);
+                assert!(b_end <= a_end);
+                b_start - a_start
+            }
+        }
+    }
+
 }
 
 #[allow(missing_doc)]
@@ -2280,10 +2231,10 @@ mod tests {
 
     #[test]
     fn test_le() {
-        assert!((le(&"", &"")));
-        assert!((le(&"", &"foo")));
-        assert!((le(&"foo", &"foo")));
-        assert!((!eq(&~"foo", &~"bar")));
+        assert!("" <= "");
+        assert!("" <= "foo");
+        assert!("foo" <= "foo");
+        assert!("foo" != ~"bar");
     }
 
     #[test]
@@ -3003,15 +2954,15 @@ mod tests {
         let a = "kernelsprite";
         let b = a.slice(7, a.len());
         let c = a.slice(0, a.len() - 6);
-        assert_eq!(subslice_offset(a, b), 7);
-        assert_eq!(subslice_offset(a, c), 0);
+        assert_eq!(a.subslice_offset(b), 7);
+        assert_eq!(a.subslice_offset(c), 0);
 
         let string = "a\nb\nc";
         let mut lines = ~[];
         for string.line_iter().advance |line| { lines.push(line) }
-        assert_eq!(subslice_offset(string, lines[0]), 0);
-        assert_eq!(subslice_offset(string, lines[1]), 2);
-        assert_eq!(subslice_offset(string, lines[2]), 4);
+        assert_eq!(string.subslice_offset(lines[0]), 0);
+        assert_eq!(string.subslice_offset(lines[1]), 2);
+        assert_eq!(string.subslice_offset(lines[2]), 4);
     }
 
     #[test]
@@ -3019,7 +2970,7 @@ mod tests {
     fn test_subslice_offset_2() {
         let a = "alchemiter";
         let b = "cruxtruder";
-        subslice_offset(a, b);
+        a.subslice_offset(b);
     }
 
     #[test]
@@ -3069,8 +3020,8 @@ mod tests {
 
     #[test]
     fn test_map() {
-        assert_eq!(~"", map("", |c| unsafe {libc::toupper(c as c_char)} as char));
-        assert_eq!(~"YMCA", map("ymca", |c| unsafe {libc::toupper(c as c_char)} as char));
+        assert_eq!(~"", "".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
+        assert_eq!(~"YMCA", "ymca".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
     }
 
     #[test]
@@ -3114,10 +3065,10 @@ mod tests {
 
         for pairs.each |p| {
             let (s, u) = copy *p;
-            assert!(to_utf16(s) == u);
+            assert!(s.to_utf16() == u);
             assert!(from_utf16(u) == s);
-            assert!(from_utf16(to_utf16(s)) == s);
-            assert!(to_utf16(from_utf16(u)) == u);
+            assert!(from_utf16(s.to_utf16()) == s);
+            assert!(from_utf16(u).to_utf16() == u);
         }
     }
 
@@ -3189,6 +3140,24 @@ mod tests {
     }
 
     #[test]
+    fn test_add() {
+        macro_rules! t (
+            ($s1:expr, $s2:expr, $e:expr) => {
+                assert_eq!($s1 + $s2, $e);
+                assert_eq!($s1.to_owned() + $s2, $e);
+                assert_eq!($s1.to_managed() + $s2, $e);
+            }
+        );
+
+        t!("foo",  "bar", ~"foobar");
+        t!("foo", @"bar", ~"foobar");
+        t!("foo", ~"bar", ~"foobar");
+        t!("ศไทย中",  "华Việt Nam", ~"ศไทย中华Việt Nam");
+        t!("ศไทย中", @"华Việt Nam", ~"ศไทย中华Việt Nam");
+        t!("ศไทย中", ~"华Việt Nam", ~"ศไทย中华Việt Nam");
+    }
+
+    #[test]
     fn test_iterator() {
         use iterator::*;
         let s = ~"ศไทย中华Việt Nam";
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 25166eca7bb..44e480dc7df 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -39,8 +39,6 @@ pub mod rt {
     use parse;
     use print::pprust;
 
-    use core::str;
-
     pub use ast::*;
     pub use parse::token::*;
     pub use parse::new_parser_from_tts;
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 035675e523e..c1bf979cd31 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -969,7 +969,7 @@ mod test {
     // change every identifier to "zz"
     pub fn to_zz() -> @fn(ast::ident)->ast::ident {
         let zz_id = token::str_to_ident("zz");
-        |id| {zz_id}
+        |_id| {zz_id}
     }
 
     // maybe add to expand.rs...
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index b7bb1b3bc53..40352f890f4 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -89,12 +89,11 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
         }
 
         return do lines.map |line| {
-            let mut chars = ~[];
-            for line.iter().advance |c| { chars.push(c) }
+            let chars = line.iter().collect::<~[char]>();
             if i > chars.len() {
                 ~""
             } else {
-                str::from_chars(chars.slice(i, chars.len()).to_owned())
+                str::from_chars(chars.slice(i, chars.len()))
             }
         };
     }
@@ -103,14 +102,13 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
         // FIXME #5475:
         // return comment.slice(3u, comment.len()).trim().to_owned();
         let r = comment.slice(3u, comment.len()); return r.trim().to_owned();
-
     }
 
     if comment.starts_with("/*") {
-        let mut lines = ~[];
-        for str::each_line_any(comment.slice(3u, comment.len() - 2u)) |line| {
-            lines.push(line.to_owned())
-        }
+        let lines = comment.slice(3u, comment.len() - 2u)
+            .any_line_iter()
+            .transform(|s| s.to_owned())
+            .collect::<~[~str]>();
         let lines = vertical_trim(lines);
         let lines = block_trim(lines, ~"\t ", None);
         let lines = block_trim(lines, ~"*", Some(1u));