about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-21 07:06:54 -0700
committerbors <bors@rust-lang.org>2013-03-21 07:06:54 -0700
commitb8899138f88e50841829c471b2705f2e796b9a1f (patch)
tree5997e6dc0d2eebe56179771e1a58f0acd7895f1a
parent0b4f2687cec898e52c47d1d93fb6317f2f4b468b (diff)
parent9d9a209e9a61414cdf9c8065d445ce353d6ed45f (diff)
downloadrust-b8899138f88e50841829c471b2705f2e796b9a1f.tar.gz
rust-b8899138f88e50841829c471b2705f2e796b9a1f.zip
auto merge of #5466 : Kimundi/rust/view-slice-rename, r=bstrie
A slice now always refers to something that returns an borrowed pointer, views don't exist anymore. If you want to have an explictit copy of a slice, use `to_owned()`
-rw-r--r--src/compiletest/errors.rs4
-rw-r--r--src/compiletest/header.rs2
-rw-r--r--src/libcore/num/strconv.rs6
-rw-r--r--src/libcore/path.rs16
-rw-r--r--src/libcore/rt/uv.rs2
-rw-r--r--src/libcore/run.rs4
-rw-r--r--src/libcore/str.rs148
-rw-r--r--src/libcore/unstable/extfmt.rs2
-rw-r--r--src/libcore/vec.rs26
-rw-r--r--src/libfuzzer/fuzzer.rc2
-rw-r--r--src/librustc/back/link.rs2
-rw-r--r--src/librustc/metadata/encoder.rs2
-rw-r--r--src/librustc/middle/lint.rs4
-rw-r--r--src/librustc/middle/trans/common.rs2
-rw-r--r--src/librustc/middle/trans/debuginfo.rs6
-rw-r--r--src/librustc/util/ppaux.rs2
-rw-r--r--src/librustdoc/desc_to_brief_pass.rs2
-rw-r--r--src/librustdoc/markdown_writer.rs2
-rw-r--r--src/librustdoc/sectionalize_pass.rs2
-rw-r--r--src/librustdoc/unindent_pass.rs2
-rw-r--r--src/libstd/bitv.rs6
-rw-r--r--src/libstd/flatpipes.rs2
-rw-r--r--src/libstd/getopts.rs4
-rw-r--r--src/libstd/net_url.rs40
-rw-r--r--src/libstd/rope.rs2
-rw-r--r--src/libstd/sha1.rs2
-rw-r--r--src/libsyntax/codemap.rs4
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs2
-rw-r--r--src/libsyntax/parse/comments.rs8
-rw-r--r--src/libsyntax/parse/lexer.rs2
-rw-r--r--src/test/compile-fail/issue-3888.rs2
31 files changed, 151 insertions, 161 deletions
diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs
index 16af0a4b575..63b5c64c6d4 100644
--- a/src/compiletest/errors.rs
+++ b/src/compiletest/errors.rs
@@ -51,11 +51,11 @@ fn parse_expected(line_num: uint, line: ~str) -> ~[ExpectedError] {
         while idx < len && line[idx] == (' ' as u8) { idx += 1u; }
         let start_kind = idx;
         while idx < len && line[idx] != (' ' as u8) { idx += 1u; }
-        let kind = str::to_lower(str::slice(line, start_kind, idx));
+        let kind = str::to_lower(str::slice(line, start_kind, idx).to_owned());
 
         // Extract msg:
         while idx < len && line[idx] == (' ' as u8) { idx += 1u; }
-        let msg = str::slice(line, idx, len);
+        let msg = str::slice(line, idx, len).to_owned();
 
         debug!("line=%u kind=%s msg=%s", line_num - adjust_line, kind, msg);
 
diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs
index 7d0a4d7dcc8..a039aaf5683 100644
--- a/src/compiletest/header.rs
+++ b/src/compiletest/header.rs
@@ -175,7 +175,7 @@ fn parse_name_value_directive(line: ~str,
         match str::find_str(line, keycolon) {
             Some(colon) => {
                 let value = str::slice(line, colon + str::len(keycolon),
-                                       str::len(line));
+                                       str::len(line)).to_owned();
                 debug!("%s: %s", directive,  value);
                 Some(value)
             }
diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs
index d471eda74c6..28e57a354c8 100644
--- a/src/libcore/num/strconv.rs
+++ b/src/libcore/num/strconv.rs
@@ -364,14 +364,14 @@ pub pure fn to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Copy+
 
             // only resize buf if we actually remove digits
             if i < buf_max_i {
-                buf = buf.slice(0, i + 1);
+                buf = buf.slice(0, i + 1).to_owned();
             }
         }
     } // If exact and trailing '.', just cut that
     else {
         let max_i = buf.len() - 1;
         if buf[max_i] == '.' as u8 {
-            buf = buf.slice(0, max_i);
+            buf = buf.slice(0, max_i).to_owned();
         }
     }
 
@@ -606,7 +606,7 @@ pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
         // parse remaining bytes as decimal integer,
         // skipping the exponent char
         let exp: Option<int> = from_str_bytes_common(
-            buf.view(i+1, len), 10, true, false, false, ExpNone, false);
+            buf.slice(i+1, len), 10, true, false, false, ExpNone, false);
 
         match exp {
             Some(exp_pow) => {
diff --git a/src/libcore/path.rs b/src/libcore/path.rs
index c6886074007..bc6d6b507b2 100644
--- a/src/libcore/path.rs
+++ b/src/libcore/path.rs
@@ -410,7 +410,7 @@ impl GenericPath for PosixPath {
           None => None,
           Some(ref f) => {
             match str::rfind_char(*f, '.') {
-              Some(p) => Some(f.slice(0, p)),
+              Some(p) => Some(f.slice(0, p).to_owned()),
               None => Some(copy *f)
             }
           }
@@ -422,7 +422,7 @@ impl GenericPath for PosixPath {
           None => None,
           Some(ref f) => {
             match str::rfind_char(*f, '.') {
-              Some(p) if p < f.len() => Some(f.slice(p, f.len())),
+              Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()),
               _ => None
             }
           }
@@ -622,7 +622,7 @@ impl GenericPath for WindowsPath {
           None => None,
           Some(ref f) => {
             match str::rfind_char(*f, '.') {
-              Some(p) => Some(f.slice(0, p)),
+              Some(p) => Some(f.slice(0, p).to_owned()),
               None => Some(copy *f)
             }
           }
@@ -634,7 +634,7 @@ impl GenericPath for WindowsPath {
           None => None,
           Some(ref f) => {
             match str::rfind_char(*f, '.') {
-              Some(p) if p < f.len() => Some(f.slice(p, f.len())),
+              Some(p) if p < f.len() => Some(f.slice(p, f.len()).to_owned()),
               _ => None
             }
           }
@@ -842,8 +842,8 @@ pub mod windows {
             let mut i = 2;
             while i < s.len() {
                 if is_sep(s[i]) {
-                    let pre = s.slice(2, i);
-                    let mut rest = s.slice(i, s.len());
+                    let pre = s.slice(2, i).to_owned();
+                    let mut rest = s.slice(i, s.len()).to_owned();
                     return Some((pre, rest));
                 }
                 i += 1;
@@ -860,9 +860,9 @@ pub mod windows {
                 let rest = if s.len() == 2 {
                     ~""
                 } else {
-                    s.slice(2, s.len())
+                    s.slice(2, s.len()).to_owned()
                 };
-                return Some((s.slice(0,1), rest));
+                return Some((s.slice(0,1).to_owned(), rest));
             }
             None
         }
diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs
index 80224fa523a..e57d0f51870 100644
--- a/src/libcore/rt/uv.rs
+++ b/src/libcore/rt/uv.rs
@@ -878,7 +878,7 @@ fn listen() {
                 if status.is_none() {
                     rtdebug!("got %d bytes", nread);
                     let buf = buf.unwrap();
-                    for buf.view(0, nread as uint).each |byte| {
+                    for buf.slice(0, nread as uint).each |byte| {
                         fail_unless!(*byte == count as u8);
                         rtdebug!("%u", *byte as uint);
                         count += 1;
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index d3affbc69fe..5fbb5e3c223 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -303,7 +303,7 @@ fn read_all(rd: io::Reader) -> ~str {
         let mut bytes = [0, ..4096];
         while !rd.eof() {
             let nread = rd.read(bytes, bytes.len());
-            wr.write(bytes.view(0, nread));
+            wr.write(bytes.slice(0, nread));
         }
     });
     str::from_bytes(buf)
@@ -404,7 +404,7 @@ pub fn readclose(fd: c_int) -> ~str {
             let mut bytes = [0, ..4096];
             while !reader.eof() {
                 let nread = reader.read(bytes, bytes.len());
-                writer.write(bytes.view(0, nread));
+                writer.write(bytes.slice(0, nread));
             }
         });
         os::fclose(file);
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 748cea50e90..3d704b42a0e 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -50,7 +50,7 @@ pub pure fn from_bytes(vv: &[const u8]) -> ~str {
 
 /// Copy a slice into a new unique str
 pub pure fn from_slice(s: &str) -> ~str {
-    unsafe { raw::slice_bytes(s, 0, len(s)) }
+    unsafe { raw::slice_bytes_unique(s, 0, len(s)) }
 }
 
 /**
@@ -265,7 +265,7 @@ pub fn pop_char(s: &mut ~str) -> char {
  */
 pub fn shift_char(s: &mut ~str) -> char {
     let CharRange {ch, next} = char_range_at(*s, 0u);
-    *s = unsafe { raw::slice_bytes(*s, next, len(*s)) };
+    *s = unsafe { raw::slice_bytes_unique(*s, next, len(*s)) };
     return ch;
 }
 
@@ -279,9 +279,9 @@ pub fn shift_char(s: &mut ~str) -> char {
  * If the string does not contain any characters
  */
 #[inline]
-pub fn view_shift_char(s: &'a str) -> (char, &'a str) {
+pub fn slice_shift_char(s: &'a str) -> (char, &'a str) {
     let CharRange {ch, next} = char_range_at(s, 0u);
-    let next_s = unsafe { raw::view_bytes(s, next, len(s)) };
+    let next_s = unsafe { raw::slice_bytes(s, next, len(s)) };
     return (ch, next_s);
 }
 
@@ -304,7 +304,7 @@ pub pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str {
 
     match find(s, |c| !chars_to_trim.contains(&c)) {
       None => ~"",
-      Some(first) => unsafe { raw::slice_bytes(s, first, s.len()) }
+      Some(first) => unsafe { raw::slice_bytes_unique(s, first, s.len()) }
     }
 }
 
@@ -324,7 +324,7 @@ pub pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str {
       None => ~"",
       Some(last) => {
         let next = char_range_at(s, last).next;
-        unsafe { raw::slice_bytes(s, 0u, next) }
+        unsafe { raw::slice_bytes_unique(s, 0u, next) }
       }
     }
 }
@@ -346,7 +346,7 @@ pub pure fn trim_chars(s: &str, chars_to_trim: &[char]) -> ~str {
 pub pure fn trim_left(s: &str) -> ~str {
     match find(s, |c| !char::is_whitespace(c)) {
       None => ~"",
-      Some(first) => unsafe { raw::slice_bytes(s, first, len(s)) }
+      Some(first) => unsafe { raw::slice_bytes_unique(s, first, len(s)) }
     }
 }
 
@@ -356,7 +356,7 @@ pub pure fn trim_right(s: &str) -> ~str {
       None => ~"",
       Some(last) => {
         let next = char_range_at(s, last).next;
-        unsafe { raw::slice_bytes(s, 0u, next) }
+        unsafe { raw::slice_bytes_unique(s, 0u, next) }
       }
     }
 }
@@ -408,31 +408,19 @@ pub pure fn chars(s: &str) -> ~[char] {
  * `begin`.
  */
 pub pure fn substr(s: &str, begin: uint, n: uint) -> ~str {
-    slice(s, begin, begin + count_bytes(s, begin, n))
+    slice(s, begin, begin + count_bytes(s, begin, n)).to_owned()
 }
 
 /**
  * Returns a slice of the given string from the byte range [`begin`..`end`)
  *
- * Fails when `begin` and `end` do not point to valid characters or
- * beyond the last character of the string
- */
-pub pure fn slice(s: &str, begin: uint, end: uint) -> ~str {
-    fail_unless!(is_char_boundary(s, begin));
-    fail_unless!(is_char_boundary(s, end));
-    unsafe { raw::slice_bytes(s, begin, end) }
-}
-
-/**
- * Returns a view of the given string from the byte range [`begin`..`end`)
- *
  * Fails when `begin` and `end` do not point to valid characters or beyond
  * the last character of the string
  */
-pub pure fn view(s: &'a str, begin: uint, end: uint) -> &'a str {
+pub pure fn slice(s: &'a str, begin: uint, end: uint) -> &'a str {
     fail_unless!(is_char_boundary(s, begin));
     fail_unless!(is_char_boundary(s, end));
-    unsafe { raw::view_bytes(s, begin, end) }
+    unsafe { raw::slice_bytes(s, begin, end) }
 }
 
 /// Splits a string into substrings at each occurrence of a given character
@@ -465,7 +453,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool)
             if s[i] == b {
                 if allow_empty || start < i {
                     unsafe {
-                        result.push(raw::slice_bytes(s, start, i));
+                        result.push(raw::slice_bytes_unique(s, start, i));
                     }
                 }
                 start = i + 1u;
@@ -474,7 +462,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool)
             i += 1u;
         }
         if allow_empty || start < l {
-            unsafe { result.push(raw::slice_bytes(s, start, l) ) };
+            unsafe { result.push(raw::slice_bytes_unique(s, start, l) ) };
         }
         result
     } else {
@@ -513,7 +501,7 @@ pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint,
         if sepfn(ch) {
             if allow_empty || start < i {
                 unsafe {
-                    result.push(raw::slice_bytes(s, start, i));
+                    result.push(raw::slice_bytes_unique(s, start, i));
                 }
             }
             start = next;
@@ -523,7 +511,7 @@ pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint,
     }
     if allow_empty || start < l {
         unsafe {
-            result.push(raw::slice_bytes(s, start, l));
+            result.push(raw::slice_bytes_unique(s, start, l));
         }
     }
     result
@@ -578,7 +566,7 @@ pure fn iter_between_matches(s: &'a str, sep: &'b str, f: &fn(uint, uint)) {
 pub pure fn split_str(s: &'a str, sep: &'b str) -> ~[~str] {
     let mut result = ~[];
     do iter_between_matches(s, sep) |from, to| {
-        unsafe { result.push(raw::slice_bytes(s, from, to)); }
+        unsafe { result.push(raw::slice_bytes_unique(s, from, to)); }
     }
     result
 }
@@ -587,7 +575,7 @@ pub pure fn split_str_nonempty(s: &'a str, sep: &'b str) -> ~[~str] {
     let mut result = ~[];
     do iter_between_matches(s, sep) |from, to| {
         if to > from {
-            unsafe { result.push(raw::slice_bytes(s, from, to)); }
+            unsafe { result.push(raw::slice_bytes_unique(s, from, to)); }
         }
     }
     result
@@ -721,7 +709,7 @@ pub pure fn replace(s: &str, from: &str, to: &str) -> ~str {
         } else {
             unsafe { push_str(&mut result, to); }
         }
-        unsafe { push_str(&mut result, raw::slice_bytes(s, start, end)); }
+        unsafe { push_str(&mut result, raw::slice_bytes_unique(s, start, end)); }
     }
     result
 }
@@ -2135,7 +2123,7 @@ pub mod raw {
      * If begin is greater than end.
      * If end is greater than the length of the string.
      */
-    pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str {
+    pub unsafe fn slice_bytes_unique(s: &str, begin: uint, end: uint) -> ~str {
         do as_buf(s) |sbuf, n| {
             fail_unless!((begin <= end));
             fail_unless!((end <= n));
@@ -2155,7 +2143,7 @@ pub mod raw {
     }
 
     /**
-     * Takes a bytewise (not UTF-8) view from a string.
+     * Takes a bytewise (not UTF-8) slice from a string.
      *
      * Returns the substring from [`begin`..`end`).
      *
@@ -2165,7 +2153,7 @@ pub mod raw {
      * If end is greater than the length of the string.
      */
     #[inline]
-    pub unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str {
+    pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
         do as_buf(s) |sbuf, n| {
              fail_unless!((begin <= end));
              fail_unless!((end <= n));
@@ -2207,7 +2195,7 @@ pub mod raw {
         let len = len(*s);
         fail_unless!((len > 0u));
         let b = s[0];
-        *s = unsafe { raw::slice_bytes(*s, 1u, len) };
+        *s = unsafe { raw::slice_bytes_unique(*s, 1u, len) };
         return b;
     }
 
@@ -2287,7 +2275,7 @@ pub trait StrSlice {
     pure fn is_alphanumeric(&self) -> bool;
     pure fn len(&self) -> uint;
     pure fn char_len(&self) -> uint;
-    pure fn slice(&self, begin: uint, end: uint) -> ~str;
+    pure fn slice(&self, begin: uint, end: uint) -> &'self str;
     pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str];
     pure fn split_char(&self, sep: char) -> ~[~str];
     pure fn split_str(&self, sep: &'a str) -> ~[~str];
@@ -2402,7 +2390,7 @@ impl StrSlice for &'self str {
      * beyond the last character of the string
      */
     #[inline]
-    pure fn slice(&self, begin: uint, end: uint) -> ~str {
+    pure fn slice(&self, begin: uint, end: uint) -> &'self str {
         slice(*self, begin, end)
     }
     /// Splits a string into substrings using a character function
@@ -2460,7 +2448,7 @@ impl StrSlice for &'self str {
     pure fn trim_right(&self) -> ~str { trim_right(*self) }
 
     #[inline]
-    pure fn to_owned(&self) -> ~str { self.slice(0, self.len()) }
+    pure fn to_owned(&self) -> ~str { from_slice(*self) }
 
     #[inline]
     pure fn to_managed(&self) -> @str {
@@ -2523,8 +2511,8 @@ mod tests {
 
     #[test]
     fn test_eq_slice() {
-        fail_unless!((eq_slice(view("foobar", 0, 3), "foo")));
-        fail_unless!((eq_slice(view("barfoo", 3, 6), "foo")));
+        fail_unless!((eq_slice(slice("foobar", 0, 3), "foo")));
+        fail_unless!((eq_slice(slice("barfoo", 3, 6), "foo")));
         fail_unless!((!eq_slice("foo1", "foo2")));
     }
 
@@ -2891,25 +2879,24 @@ mod tests {
 
     #[test]
     fn test_unsafe_slice() {
-        unsafe {
-            fail_unless!(~"ab" == raw::slice_bytes(~"abc", 0, 2));
-            fail_unless!(~"bc" == raw::slice_bytes(~"abc", 1, 3));
-            fail_unless!(~"" == raw::slice_bytes(~"abc", 1, 1));
-            fn a_million_letter_a() -> ~str {
-                let mut i = 0;
-                let mut rs = ~"";
-                while i < 100000 { push_str(&mut rs, ~"aaaaaaaaaa"); i += 1; }
-                rs
-            }
-            fn half_a_million_letter_a() -> ~str {
-                let mut i = 0;
-                let mut rs = ~"";
-                while i < 100000 { push_str(&mut rs, ~"aaaaa"); i += 1; }
-                rs
-            }
-            fail_unless!(half_a_million_letter_a() ==
-                raw::slice_bytes(a_million_letter_a(), 0u, 500000));
+        fail_unless!("ab" == unsafe {raw::slice_bytes("abc", 0, 2)});
+        fail_unless!("bc" == unsafe {raw::slice_bytes("abc", 1, 3)});
+        fail_unless!("" == unsafe {raw::slice_bytes("abc", 1, 1)});
+        fn a_million_letter_a() -> ~str {
+            let mut i = 0;
+            let mut rs = ~"";
+            while i < 100000 { push_str(&mut rs, "aaaaaaaaaa"); i += 1; }
+            rs
         }
+        fn half_a_million_letter_a() -> ~str {
+            let mut i = 0;
+            let mut rs = ~"";
+            while i < 100000 { push_str(&mut rs, "aaaaa"); i += 1; }
+            rs
+        }
+        let letters = a_million_letter_a();
+        fail_unless!(half_a_million_letter_a() ==
+            unsafe {raw::slice_bytes(letters, 0u, 500000)}.to_owned());
     }
 
     #[test]
@@ -2989,22 +2976,22 @@ mod tests {
 
     #[test]
     fn test_slice() {
-        fail_unless!(~"ab" == slice(~"abc", 0, 2));
-        fail_unless!(~"bc" == slice(~"abc", 1, 3));
-        fail_unless!(~"" == slice(~"abc", 1, 1));
-        fail_unless!(~"\u65e5" == slice(~"\u65e5\u672c", 0, 3));
+        fail_unless!("ab" == slice("abc", 0, 2));
+        fail_unless!("bc" == slice("abc", 1, 3));
+        fail_unless!("" == slice("abc", 1, 1));
+        fail_unless!("\u65e5" == slice("\u65e5\u672c", 0, 3));
 
-        let data = ~"ประเทศไทย中华";
-        fail_unless!(~"ป" == slice(data, 0, 3));
-        fail_unless!(~"ร" == slice(data, 3, 6));
-        fail_unless!(~"" == slice(data, 3, 3));
-        fail_unless!(~"华" == slice(data, 30, 33));
+        let data = "ประเทศไทย中华";
+        fail_unless!("ป" == slice(data, 0, 3));
+        fail_unless!("ร" == slice(data, 3, 6));
+        fail_unless!("" == slice(data, 3, 3));
+        fail_unless!("华" == slice(data, 30, 33));
 
         fn a_million_letter_X() -> ~str {
             let mut i = 0;
             let mut rs = ~"";
             while i < 100000 {
-                push_str(&mut rs, ~"华华华华华华华华华华");
+                push_str(&mut rs, "华华华华华华华华华华");
                 i += 1;
             }
             rs
@@ -3012,27 +2999,28 @@ mod tests {
         fn half_a_million_letter_X() -> ~str {
             let mut i = 0;
             let mut rs = ~"";
-            while i < 100000 { push_str(&mut rs, ~"华华华华华"); i += 1; }
+            while i < 100000 { push_str(&mut rs, "华华华华华"); i += 1; }
             rs
         }
+        let letters = a_million_letter_X();
         fail_unless!(half_a_million_letter_X() ==
-            slice(a_million_letter_X(), 0u, 3u * 500000u));
+            slice(letters, 0u, 3u * 500000u).to_owned());
     }
 
     #[test]
     fn test_slice_2() {
-        let ss = ~"中华Việt Nam";
+        let ss = "中华Việt Nam";
 
-        fail_unless!(~"华" == slice(ss, 3u, 6u));
-        fail_unless!(~"Việt Nam" == slice(ss, 6u, 16u));
+        fail_unless!("华" == slice(ss, 3u, 6u));
+        fail_unless!("Việt Nam" == slice(ss, 6u, 16u));
 
-        fail_unless!(~"ab" == slice(~"abc", 0u, 2u));
-        fail_unless!(~"bc" == slice(~"abc", 1u, 3u));
-        fail_unless!(~"" == slice(~"abc", 1u, 1u));
+        fail_unless!("ab" == slice("abc", 0u, 2u));
+        fail_unless!("bc" == slice("abc", 1u, 3u));
+        fail_unless!("" == slice("abc", 1u, 1u));
 
-        fail_unless!(~"中" == slice(ss, 0u, 3u));
-        fail_unless!(~"华V" == slice(ss, 3u, 7u));
-        fail_unless!(~"" == slice(ss, 3u, 3u));
+        fail_unless!("中" == slice(ss, 0u, 3u));
+        fail_unless!("华V" == slice(ss, 3u, 7u));
+        fail_unless!("" == slice(ss, 3u, 3u));
         /*0: 中
           3: 华
           6: V
@@ -3049,7 +3037,7 @@ mod tests {
     #[should_fail]
     #[ignore(cfg(windows))]
     fn test_slice_fail() {
-        slice(~"中华Việt Nam", 0u, 2u);
+        slice("中华Việt Nam", 0u, 2u);
     }
 
     #[test]
@@ -3645,7 +3633,7 @@ mod tests {
     #[test]
     fn test_to_managed() {
         fail_unless!((~"abc").to_managed() == @"abc");
-        fail_unless!(view("abcdef", 1, 5).to_managed() == @"bcde");
+        fail_unless!(slice("abcdef", 1, 5).to_managed() == @"bcde");
     }
 
     #[test]
diff --git a/src/libcore/unstable/extfmt.rs b/src/libcore/unstable/extfmt.rs
index 45766e97260..0f41ca8c41a 100644
--- a/src/libcore/unstable/extfmt.rs
+++ b/src/libcore/unstable/extfmt.rs
@@ -164,7 +164,7 @@ pub mod ct {
     pub fn parse_fmt_string(s: &str, err: ErrorFn) -> ~[Piece] {
         fn push_slice(ps: &mut ~[Piece], s: &str, from: uint, to: uint) {
             if to > from {
-                ps.push(PieceString(s.slice(from, to)));
+                ps.push(PieceString(s.slice(from, to).to_owned()));
             }
         }
 
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index e41aefc94e5..2e20e859d55 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -1707,27 +1707,29 @@ impl<T> Container for &'self [const T] {
 }
 
 pub trait CopyableVector<T> {
-    pure fn slice(&self, start: uint, end: uint) -> ~[T];
+    pure fn to_owned(&self) -> ~[T];
 }
 
 /// Extension methods for vectors
 impl<T: Copy> CopyableVector<T> for &'self [const T] {
-    /// Returns a copy of the elements from [`start`..`end`) from `v`.
+    /// Returns a copy of `v`.
     #[inline]
-    pure fn slice(&self, start: uint, end: uint) -> ~[T] {
-        // XXX: Purity workaround for stage0.
+    pure fn to_owned(&self) -> ~[T] {
+        let mut result = ~[];
+        // FIXME: #4568
         unsafe {
-            let mut result = ~[];
-            for uint::range(start, end) |i| {
-                result.push(copy self[i]);
+            reserve(&mut result, self.len());
+            for self.each |e| {
+                result.push(copy *e);
             }
-            result
         }
+        result
+
     }
 }
 
 pub trait ImmutableVector<T> {
-    pure fn view(&self, start: uint, end: uint) -> &'self [T];
+    pure fn slice(&self, start: uint, end: uint) -> &'self [T];
     pure fn head(&self) -> &'self T;
     pure fn head_opt(&self) -> Option<&'self T>;
     pure fn tail(&self) -> &'self [T];
@@ -1751,7 +1753,7 @@ pub trait ImmutableVector<T> {
 impl<T> ImmutableVector<T> for &'self [T] {
     /// Return a slice that points into another slice.
     #[inline]
-    pure fn view(&self, start: uint, end: uint) -> &'self [T] {
+    pure fn slice(&self, start: uint, end: uint) -> &'self [T] {
         slice(*self, start, end)
     }
 
@@ -3613,9 +3615,9 @@ mod tests {
     }
 
     #[test]
-    fn test_view() {
+    fn test_slice_2() {
         let v = ~[1, 2, 3, 4, 5];
-        let v = v.view(1u, 3u);
+        let v = v.slice(1u, 3u);
         fail_unless!(v.len() == 2u);
         fail_unless!(v[0] == 2);
         fail_unless!(v[1] == 3);
diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc
index ce554f34731..3a2bbcee4b0 100644
--- a/src/libfuzzer/fuzzer.rc
+++ b/src/libfuzzer/fuzzer.rc
@@ -336,7 +336,7 @@ pub fn check_variants_T<T: Copy>(
 
 pub fn last_part(filename: ~str) -> ~str {
   let ix = option::get(str::rfind_char(filename, '/'));
-  str::slice(filename, ix + 1u, str::len(filename) - 3u)
+  str::slice(filename, ix + 1u, str::len(filename) - 3u).to_owned()
 }
 
 pub enum happiness {
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index 4e83a1065c6..4c8f2716781 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -771,7 +771,7 @@ pub fn link_binary(sess: Session,
     fn unlib(config: @session::config, +stem: ~str) -> ~str {
         if stem.starts_with("lib") &&
             config.os != session::os_win32 {
-            stem.slice(3, stem.len())
+            stem.slice(3, stem.len()).to_owned()
         } else {
             stem
         }
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index f057b04e066..6bb10a42f3e 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1239,7 +1239,7 @@ fn encode_crate_deps(ecx: @EncodeContext,
         }
 
         // mut -> immutable hack for vec::map
-        deps.slice(0, deps.len())
+        deps.slice(0, deps.len()).to_owned()
     }
 
     // We're just going to write a list of crate 'name-hash-version's, with
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index a8fe25b61c7..3edceebba0c 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -888,14 +888,14 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) {
 
     fn ident_without_trailing_underscores(ident: &'r str) -> &'r str {
         match str::rfind(ident, |c| c != '_') {
-            Some(idx) => str::view(ident, 0, idx + 1),
+            Some(idx) => str::slice(ident, 0, idx + 1),
             None => ident, // all underscores
         }
     }
 
     fn ident_without_leading_underscores(ident: &'r str) -> &'r str {
         match str::find(ident, |c| c != '_') {
-            Some(idx) => str::view(ident, idx, ident.len()),
+            Some(idx) => str::slice(ident, idx, ident.len()),
             None => ident // all underscores
         }
     }
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 8c95ee4fd96..8ffccff54b8 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -1430,7 +1430,7 @@ pub fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
 
     // Vtables are stored in a flat array, finding the right one is
     // somewhat awkward
-    let first_n_bounds = ps.bounds.view(0, n_param);
+    let first_n_bounds = ps.bounds.slice(0, n_param);
     let vtables_to_skip =
         ty::count_traits_and_supertraits(tcx, first_n_bounds);
     let vtable_off = vtables_to_skip + n_bound;
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index f74f83e4573..c575465ddf7 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -251,10 +251,10 @@ fn get_cache(cx: @CrateContext) -> metadata_cache {
 fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
     (if str::starts_with(full_path, work_dir) {
         str::slice(full_path, str::len(work_dir) + 1u,
-                   str::len(full_path))
+                   str::len(full_path)).to_owned()
     } else {
-        str::from_slice(full_path)
-    }, str::from_slice(work_dir))
+        full_path.to_owned()
+    }, work_dir.to_owned())
 }
 
 fn create_file(cx: @CrateContext, +full_path: ~str)
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index c332d3ac674..eb63d675d80 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -488,7 +488,7 @@ pub fn parameterized(cx: ctxt,
 
 pub fn ty_to_short_str(cx: ctxt, typ: t) -> ~str {
     let mut s = encoder::encoded_ty(cx, typ);
-    if str::len(s) >= 32u { s = str::slice(s, 0u, 32u); }
+    if str::len(s) >= 32u { s = str::slice(s, 0u, 32u).to_owned(); }
     return s;
 }
 
diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs
index 51574c2c3c7..281c318eb15 100644
--- a/src/librustdoc/desc_to_brief_pass.rs
+++ b/src/librustdoc/desc_to_brief_pass.rs
@@ -171,7 +171,7 @@ fn first_sentence_(s: &str) -> ~str {
     };
     match idx {
         Some(idx) if idx > 2u => {
-            str::from_slice(str::view(s, 0, idx - 1))
+            str::from_slice(str::slice(s, 0, idx - 1))
         }
         _ => {
             if str::ends_with(s, ~".") {
diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs
index f8389732414..4c68e632f83 100644
--- a/src/librustdoc/markdown_writer.rs
+++ b/src/librustdoc/markdown_writer.rs
@@ -157,7 +157,7 @@ fn readclose(fd: libc::c_int) -> ~str {
             let mut bytes = [0, ..4096];
             while !reader.eof() {
                 let nread = reader.read(bytes, bytes.len());
-                writer.write(bytes.view(0, nread));
+                writer.write(bytes.slice(0, nread).to_owned());
             }
         });
         os::fclose(file);
diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs
index e64d4ccf69e..8b058048ff4 100644
--- a/src/librustdoc/sectionalize_pass.rs
+++ b/src/librustdoc/sectionalize_pass.rs
@@ -154,7 +154,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
 
 fn parse_header(line: ~str) -> Option<~str> {
     if str::starts_with(line, ~"# ") {
-        Some(str::slice(line, 2u, str::len(line)))
+        Some(str::slice(line, 2u, str::len(line)).to_owned())
     } else {
         None
     }
diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs
index 6edf53785cb..506dfafa247 100644
--- a/src/librustdoc/unindent_pass.rs
+++ b/src/librustdoc/unindent_pass.rs
@@ -84,7 +84,7 @@ fn unindent(s: &str) -> ~str {
                 copy *line
             } else {
                 fail_unless!(str::len(*line) >= min_indent);
-                str::slice(*line, min_indent, str::len(*line))
+                str::slice(*line, min_indent, str::len(*line)).to_owned()
             }
         };
         str::connect(unindented, ~"\n")
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index 430a5eab64e..d4b4c7b097c 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -831,7 +831,7 @@ priv impl BitvSet {
                         f: &fn(uint, uint, uint) -> bool) {
         let min = uint::min(self.bitv.storage.len(),
                             other.bitv.storage.len());
-        for self.bitv.storage.view(0, min).eachi |i, &w| {
+        for self.bitv.storage.slice(0, min).eachi |i, &w| {
             if !f(i * uint::bits, w, other.bitv.storage[i]) {
                 return;
             }
@@ -852,12 +852,12 @@ priv impl BitvSet {
         let min = uint::min(len1, len2);
 
         /* only one of these loops will execute and that's the point */
-        for self.bitv.storage.view(min, len1).eachi |i, &w| {
+        for self.bitv.storage.slice(min, len1).eachi |i, &w| {
             if !f(true, (i + min) * uint::bits, w) {
                 return;
             }
         }
-        for other.bitv.storage.view(min, len2).eachi |i, &w| {
+        for other.bitv.storage.slice(min, len2).eachi |i, &w| {
             if !f(false, (i + min) * uint::bits, w) {
                 return;
             }
diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs
index c5515c63b29..105e34761a8 100644
--- a/src/libstd/flatpipes.rs
+++ b/src/libstd/flatpipes.rs
@@ -571,7 +571,7 @@ pub mod bytepipes {
         fn try_recv(&self, count: uint) -> Option<~[u8]> {
             if vec::uniq_len(&const self.buf) >= count {
                 let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
-                self.buf = bytes.slice(count, bytes.len());
+                self.buf = bytes.slice(count, bytes.len()).to_owned();
                 bytes.truncate(count);
                 return Some(bytes);
             } else if vec::uniq_len(&const self.buf) > 0 {
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index 0b615e0c0da..e2702b7d566 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -243,7 +243,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
                 let mut names;
                 let mut i_arg = None;
                 if cur[1] == '-' as u8 {
-                    let tail = str::slice(cur, 2, curlen);
+                    let tail = str::slice(cur, 2, curlen).to_owned();
                     let tail_eq = str::splitn_char(tail, '=', 1);
                     if tail_eq.len() <= 1 {
                         names = ~[Long(tail)];
@@ -279,7 +279,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
                                   No => false
                                 };
                             if arg_follows && j < curlen {
-                                i_arg = Some(cur.slice(j, curlen));
+                                i_arg = Some(cur.slice(j, curlen).to_owned());
                                 break;
                             } else {
                                 last_valid_opt_id = None;
diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs
index 0bb8fdd3738..4943b374980 100644
--- a/src/libstd/net_url.rs
+++ b/src/libstd/net_url.rs
@@ -317,10 +317,10 @@ pure fn split_char_first(s: &str, c: char) -> (~str, ~str) {
         }
     }
     if index+mat == len {
-        return (str::slice(s, 0, index), ~"");
+        return (str::slice(s, 0, index).to_owned(), ~"");
     } else {
-        return (str::slice(s, 0, index),
-             str::slice(s, index + mat, str::len(s)));
+        return (str::slice(s, 0, index).to_owned(),
+             str::slice(s, index + mat, str::len(s)).to_owned());
     }
 }
 
@@ -386,8 +386,8 @@ pub pure fn get_scheme(rawurl: &str) -> Result<(~str, ~str), ~str> {
             if i == 0 {
                 return Err(~"url: Scheme cannot be empty.");
             } else {
-                return Ok((rawurl.slice(0,i),
-                                rawurl.slice(i+1,str::len(rawurl))));
+                return Ok((rawurl.slice(0,i).to_owned(),
+                                rawurl.slice(i+1,str::len(rawurl)).to_owned()));
             }
           }
           _ => {
@@ -489,7 +489,7 @@ pure fn get_authority(rawurl: &str) ->
               }
               Ip6Host => {
                 if colon_count > 7 {
-                    host = str::slice(rawurl, begin, i);
+                    host = str::slice(rawurl, begin, i).to_owned();
                     pos = i;
                     st = InPort;
                 }
@@ -506,13 +506,13 @@ pure fn get_authority(rawurl: &str) ->
             colon_count = 0; // reset count
             match st {
               Start => {
-                let user = str::slice(rawurl, begin, i);
+                let user = str::slice(rawurl, begin, i).to_owned();
                 userinfo = Some(UserInfo::new(user, None));
                 st = InHost;
               }
               PassHostPort => {
-                let user = str::slice(rawurl, begin, pos);
-                let pass = str::slice(rawurl, pos+1, i);
+                let user = str::slice(rawurl, begin, pos).to_owned();
+                let pass = str::slice(rawurl, pos+1, i).to_owned();
                 userinfo = Some(UserInfo::new(user, Some(pass)));
                 st = InHost;
               }
@@ -543,31 +543,31 @@ pure fn get_authority(rawurl: &str) ->
     match st {
       Start => {
         if host_is_end_plus_one() {
-            host = str::slice(rawurl, begin, end+1);
+            host = str::slice(rawurl, begin, end+1).to_owned();
         } else {
-            host = str::slice(rawurl, begin, end);
+            host = str::slice(rawurl, begin, end).to_owned();
         }
       }
       PassHostPort | Ip6Port => {
         if in != Digit {
             return Err(~"Non-digit characters in port.");
         }
-        host = str::slice(rawurl, begin, pos);
-        port = Some(str::slice(rawurl, pos+1, end));
+        host = str::slice(rawurl, begin, pos).to_owned();
+        port = Some(str::slice(rawurl, pos+1, end).to_owned());
       }
       Ip6Host | InHost => {
-        host = str::slice(rawurl, begin, end);
+        host = str::slice(rawurl, begin, end).to_owned();
       }
       InPort => {
         if in != Digit {
             return Err(~"Non-digit characters in port.");
         }
-        port = Some(str::slice(rawurl, pos+1, end));
+        port = Some(str::slice(rawurl, pos+1, end).to_owned());
       }
     }
 
     let rest = if host_is_end_plus_one() { ~"" }
-    else { str::slice(rawurl, end, len) };
+    else { str::slice(rawurl, end, len).to_owned() };
     return Ok((userinfo, host, port, rest));
 }
 
@@ -599,8 +599,8 @@ pure fn get_path(rawurl: &str, authority: bool) ->
         }
     }
 
-    return Ok((decode_component(str::slice(rawurl, 0, end)),
-                    str::slice(rawurl, end, len)));
+    return Ok((decode_component(str::slice(rawurl, 0, end).to_owned()),
+                    str::slice(rawurl, end, len).to_owned()));
 }
 
 // returns the parsed query and the fragment, if present
@@ -610,14 +610,14 @@ pure fn get_query_fragment(rawurl: &str) ->
         if str::starts_with(rawurl, ~"#") {
             let f = decode_component(str::slice(rawurl,
                                                 1,
-                                                str::len(rawurl)));
+                                                str::len(rawurl)).to_owned());
             return Ok((~[], Some(f)));
         } else {
             return Ok((~[], None));
         }
     }
     let (q, r) = split_char_first(str::slice(rawurl, 1,
-                                             str::len(rawurl)), '#');
+                                             str::len(rawurl)).to_owned(), '#');
     let f = if str::len(r) != 0 {
         Some(decode_component(r)) } else { None };
     return Ok((query_from_str(q), f));
diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs
index dd2f5b58fb9..ff7d4ec3b1c 100644
--- a/src/libstd/rope.rs
+++ b/src/libstd/rope.rs
@@ -1295,7 +1295,7 @@ mod tests {
                       node::Leaf(x) => {
                         *str += str::slice(
                             *x.content, x.byte_offset,
-                            x.byte_offset + x.byte_len);
+                            x.byte_offset + x.byte_len).to_owned();
                       }
                       node::Concat(ref x) => {
                         aux(str, x.left);
diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs
index f7e31bc7df7..077ab191e69 100644
--- a/src/libstd/sha1.rs
+++ b/src/libstd/sha1.rs
@@ -399,7 +399,7 @@ mod tests {
                 while left > 0u {
                     let take = (left + 1u) / 2u;
                     sh.input_str(str::slice(t.input, len - left,
-                                 take + len - left));
+                                 take + len - left).to_owned());
                     left = left - take;
                 }
                 let out = sh.result();
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 538f0de8c84..727d386f277 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -266,7 +266,7 @@ pub impl FileMap {
                 Some(e) => e,
                 None => str::len(*self.src)
             };
-            str::slice(*self.src, begin, end)
+            str::slice(*self.src, begin, end).to_owned()
         }
     }
 
@@ -396,7 +396,7 @@ pub impl CodeMap {
         let end = self.lookup_byte_offset(sp.hi);
         fail_unless!(begin.fm.start_pos == end.fm.start_pos);
         return str::slice(*begin.fm.src,
-                          begin.pos.to_uint(), end.pos.to_uint());
+                          begin.pos.to_uint(), end.pos.to_uint()).to_owned();
     }
 
     pub fn get_filemap(&self, filename: ~str) -> @FileMap {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index dcc84ce46fe..5a6fd6fec58 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -112,7 +112,7 @@ pub fn add_new_extension(cx: @ext_ctxt,
                             match (*tt) {
                                 // cut off delimiters; don't parse 'em
                                 tt_delim(ref tts) => {
-                                    (*tts).slice(1u,(*tts).len()-1u)
+                                    (*tts).slice(1u,(*tts).len()-1u).to_owned()
                                 }
                                 _ => cx.span_fatal(
                                     sp, ~"macro rhs must be delimited")
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 98208bf9f76..b5072e8c2b5 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -76,7 +76,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
         while j > i && lines[j - 1u].trim().is_empty() {
             j -= 1u;
         }
-        return lines.slice(i, j);
+        return lines.slice(i, j).to_owned();
     }
 
     // drop leftmost columns that contain only values in chars
@@ -103,7 +103,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
             if i > chars.len() {
                 ~""
             } else {
-                str::from_chars(chars.slice(i, chars.len()))
+                str::from_chars(chars.slice(i, chars.len()).to_owned())
             }
         };
     }
@@ -113,7 +113,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str {
     }
 
     if comment.starts_with(~"/*") {
-        let lines = str::lines_any(comment.slice(3u, comment.len() - 2u));
+        let lines = str::lines_any(comment.slice(3u, comment.len() - 2u).to_owned());
         let lines = vertical_trim(lines);
         let lines = block_trim(lines, ~"\t ", None);
         let lines = block_trim(lines, ~"*", Some(1u));
@@ -218,7 +218,7 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
     let col = col.to_uint();
     if all_whitespace(s, 0u, uint::min(len, col)) {
         if col < len {
-            s1 = str::slice(s, col, len);
+            s1 = str::slice(s, col, len).to_owned();
         } else { s1 = ~""; }
     } else { s1 = s; }
     debug!("pushing line: %s", s1);
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 90f51fe9b65..6cb4065935c 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -177,7 +177,7 @@ pub fn get_str_from(rdr: @mut StringReader, start: BytePos) -> ~str {
         // I'm pretty skeptical about this subtraction. What if there's a
         // multi-byte character before the mark?
         return str::slice(*rdr.src, start.to_uint() - 1u,
-                          byte_offset(rdr).to_uint() - 1u);
+                          byte_offset(rdr).to_uint() - 1u).to_owned();
     }
 }
 
diff --git a/src/test/compile-fail/issue-3888.rs b/src/test/compile-fail/issue-3888.rs
index 482d1e9fe8a..c9a5507f8de 100644
--- a/src/test/compile-fail/issue-3888.rs
+++ b/src/test/compile-fail/issue-3888.rs
@@ -17,7 +17,7 @@ fn vec_peek<T>(v: &'r [T]) -> Option< (&'r T, &'r [T]) > {
         let vec_len = v.len();
         let head = &v[0];
         // note: this *shouldn't* be an illegal borrow! See #3888
-        let tail = v.view(1, vec_len); //~ ERROR illegal borrow: borrowed value does not live long enough
+        let tail = v.slice(1, vec_len); //~ ERROR illegal borrow: borrowed value does not live long enough
         Some( (head, tail) )
     }
 }