about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMikhail Zabaluev <mikhail.zabaluev@gmail.com>2015-02-04 01:00:38 +0200
committerMikhail Zabaluev <mikhail.zabaluev@gmail.com>2015-02-05 13:54:26 +0200
commit3ac862816fc57fb6047986624d98f986cbfd40b9 (patch)
tree3f98052301b15a4ddb142978f7c713dc06583f31
parent2bd8ec2d197809fc0f0efccf1de14419ffb17b2b (diff)
Replace usage of slice::from_raw_buf with slice::from_raw_parts
New functions, slice::from_raw_parts and slice::from_raw_parts_mut,
are added to implement the lifetime convention as agreed in RFC PR #556.
The functions slice::from_raw_buf and slice::from_raw_mut_buf are
left deprecated for the time being.
-rw-r--r--src/libcollections/slice.rs1
-rw-r--r--src/libcore/slice.rs56
-rw-r--r--src/libflate/lib.rs2
-rw-r--r--src/librand/isaac.rs4
-rw-r--r--src/librustc/metadata/loader.rs8
-rw-r--r--src/librustdoc/html/markdown.rs28
-rw-r--r--src/libstd/ffi/c_str.rs4
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/sys/windows/os.rs4
9 files changed, 80 insertions, 29 deletions
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 4b4ea3e4c3c..2f547c72d05 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -113,6 +113,7 @@ pub use core::slice::{Iter, IterMut};
 pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
 pub use core::slice::{bytes, mut_ref_slice, ref_slice};
+pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 pub use core::slice::{from_raw_buf, from_raw_mut_buf};
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index a750e81bf59..c622baa0cc2 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1359,6 +1359,52 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 
 /// Forms a slice from a pointer and a length.
 ///
+/// The `len` argument is the number of **elements**, not the number of bytes.
+///
+/// This function is unsafe as there is no guarantee that the given pointer is
+/// valid for `len` elements, nor whether the lifetime inferred is a suitable
+/// lifetime for the returned slice.
+///
+/// # Caveat
+///
+/// The lifetime for the returned slice is inferred from its usage. To
+/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
+/// source lifetime is safe in the context, such as by providing a helper
+/// function taking the lifetime of a host value for the slice, or by explicit
+/// annotation.
+///
+/// # Example
+///
+/// ```rust
+/// use std::slice;
+///
+/// // manifest a slice out of thin air!
+/// let ptr = 0x1234 as *const uint;
+/// let amt = 10;
+/// unsafe {
+///     let slice = slice::from_raw_parts(ptr, amt);
+/// }
+/// ```
+#[inline]
+#[unstable(feature = "core")]
+pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: uint) -> &'a [T] {
+    transmute(RawSlice { data: p, len: len })
+}
+
+/// Performs the same functionality as `from_raw_parts`, except that a mutable
+/// slice is returned.
+///
+/// This function is unsafe for the same reasons as `from_raw_parts`, as well
+/// as not being able to provide a non-aliasing guarantee of the returned
+/// mutable slice.
+#[inline]
+#[unstable(feature = "core")]
+pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: uint) -> &'a mut [T] {
+    transmute(RawSlice { data: p, len: len })
+}
+
+/// Forms a slice from a pointer and a length.
+///
 /// The pointer given is actually a reference to the base of the slice. This
 /// reference is used to give a concrete lifetime to tie the returned slice to.
 /// Typically this should indicate that the slice is valid for as long as the
@@ -1383,8 +1429,9 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
 /// }
 /// ```
 #[inline]
-#[unstable(feature = "core",
-           reason = "should be renamed to from_raw_parts")]
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
+             reason = "use from_raw_parts")]
 pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
     transmute(RawSlice { data: *p, len: len })
 }
@@ -1396,8 +1443,9 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
 /// not being able to provide a non-aliasing guarantee of the returned mutable
 /// slice.
 #[inline]
-#[unstable(feature = "core",
-           reason = "should be renamed to from_raw_parts_mut")]
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
+             reason = "use from_raw_parts_mut")]
 pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
     transmute(RawSlice { data: *p, len: len })
 }
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
index a3bbba6d7b4..6c0c0000214 100644
--- a/src/libflate/lib.rs
+++ b/src/libflate/lib.rs
@@ -45,7 +45,7 @@ pub struct Bytes {
 impl Deref for Bytes {
     type Target = [u8];
     fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_mut_buf(&self.ptr.0, self.len) }
+        unsafe { slice::from_raw_parts_mut(self.ptr.0, self.len) }
     }
 }
 
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index d399c244e83..67942a7e5b6 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -246,7 +246,7 @@ impl Rand for IsaacRng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE * 4) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE * 4) as uint);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
@@ -489,7 +489,7 @@ impl Rand for Isaac64Rng {
         unsafe {
             let ptr = ret.rsl.as_mut_ptr() as *mut u8;
 
-            let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE_64 * 8) as uint);
+            let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE_64 * 8) as uint);
             other.fill_bytes(slice);
         }
         ret.cnt = 0;
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 2fb5a6b64a6..b7111d49d06 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -744,8 +744,8 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
             let mut name_buf = ptr::null();
             let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
-            let name = slice::from_raw_buf(&(name_buf as *const u8),
-                                           name_len as uint).to_vec();
+            let name = slice::from_raw_parts(name_buf as *const u8,
+                                             name_len as uint).to_vec();
             let name = String::from_utf8(name).unwrap();
             debug!("get_metadata_section: name {}", name);
             if read_meta_section_name(is_osx) == name {
@@ -756,7 +756,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
                 debug!("checking {} bytes of metadata-version stamp",
                        vlen);
                 let minsz = cmp::min(vlen, csz);
-                let buf0 = slice::from_raw_buf(&cvbuf, minsz);
+                let buf0 = slice::from_raw_parts(cvbuf, minsz);
                 let version_ok = buf0 == encoder::metadata_encoding_version;
                 if !version_ok {
                     return Err((format!("incompatible metadata version found: '{}'",
@@ -766,7 +766,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
                 let cvbuf1 = cvbuf.offset(vlen as int);
                 debug!("inflating {} bytes of compressed metadata",
                        csz - vlen);
-                let bytes = slice::from_raw_buf(&cvbuf1, csz-vlen);
+                let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
                 match flate::inflate_bytes(bytes) {
                     Some(inflated) => return Ok(MetadataVec(inflated)),
                     None => {}
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 7e08226019f..8680604d368 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -165,6 +165,13 @@ extern {
 
 }
 
+// hoedown_buffer helpers
+impl hoedown_buffer {
+    fn as_bytes(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.data, self.size as usize) }
+    }
+}
+
 /// Returns Some(code) if `s` is a line that should be stripped from
 /// documentation but used in example code. `code` is the portion of
 /// `s` that should be used in tests. (None for lines that should be
@@ -194,15 +201,13 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
 
             let opaque = opaque as *mut hoedown_html_renderer_state;
             let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
-            let text = slice::from_raw_buf(&(*orig_text).data,
-                                           (*orig_text).size as uint);
+            let text = (*orig_text).as_bytes();
             let origtext = str::from_utf8(text).unwrap();
             debug!("docblock: ==============\n{:?}\n=======", text);
             let rendered = if lang.is_null() {
                 false
             } else {
-                let rlang = slice::from_raw_buf(&(*lang).data,
-                                                (*lang).size as uint);
+                let rlang = (*lang).as_bytes();
                 let rlang = str::from_utf8(rlang).unwrap();
                 if !LangString::parse(rlang).rust {
                     (my_opaque.dfltblk)(ob, orig_text, lang,
@@ -248,9 +253,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         let s = if text.is_null() {
             "".to_string()
         } else {
-            let s = unsafe {
-                slice::from_raw_buf(&(*text).data, (*text).size as uint)
-            };
+            let s = unsafe { (*text).as_bytes() };
             str::from_utf8(s).unwrap().to_string()
         };
 
@@ -323,7 +326,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
         };
 
         if ret.is_ok() {
-            let buf = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
+            let buf = (*ob).as_bytes();
             ret = w.write_str(str::from_utf8(buf).unwrap());
         }
         hoedown_buffer_free(ob);
@@ -341,13 +344,12 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
             let block_info = if lang.is_null() {
                 LangString::all_false()
             } else {
-                let lang = slice::from_raw_buf(&(*lang).data,
-                                               (*lang).size as uint);
+                let lang = (*lang).as_bytes();
                 let s = str::from_utf8(lang).unwrap();
                 LangString::parse(s)
             };
             if !block_info.rust { return }
-            let text = slice::from_raw_buf(&(*text).data, (*text).size as uint);
+            let text = (*text).as_bytes();
             let opaque = opaque as *mut hoedown_html_renderer_state;
             let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
             let text = str::from_utf8(text).unwrap();
@@ -370,7 +372,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
             if text.is_null() {
                 tests.register_header("", level as u32);
             } else {
-                let text = slice::from_raw_buf(&(*text).data, (*text).size as uint);
+                let text = (*text).as_bytes();
                 let text = str::from_utf8(text).unwrap();
                 tests.register_header(text, level as u32);
             }
@@ -510,7 +512,7 @@ pub fn plain_summary_line(md: &str) -> String {
         hoedown_document_render(document, ob, md.as_ptr(),
                                 md.len() as libc::size_t);
         hoedown_document_free(document);
-        let plain_slice = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
+        let plain_slice = (*ob).as_bytes();
         let plain = match str::from_utf8(plain_slice) {
             Ok(s) => s.to_string(),
             Err(_) => "".to_string(),
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 2e55c007b55..fcc4509aa94 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -162,7 +162,7 @@ impl fmt::Debug for CString {
 /// ```
 pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
     let len = libc::strlen(*raw);
-    slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
+    slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
 }
 
 /// Interpret a C string as a byte slice with the nul terminator.
@@ -171,7 +171,7 @@ pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
 /// will include the nul terminator of the string.
 pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
     let len = libc::strlen(*raw) + 1;
-    slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
+    slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
 }
 
 #[cfg(test)]
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 64f9e16aee4..dcdd31639d3 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -671,7 +671,7 @@ fn real_args() -> Vec<String> {
 
         // Push it onto the list.
         let ptr = ptr as *const u16;
-        let buf = slice::from_raw_buf(&ptr, len);
+        let buf = slice::from_raw_parts(ptr, len);
         let opt_s = String::from_utf16(sys::truncate_utf16_at_nul(buf));
         opt_s.ok().expect("CommandLineToArgvW returned invalid UTF-16")
     }).collect();
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index c71e2d057c3..d8e3e6981df 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -109,7 +109,7 @@ impl Iterator for Env {
                 len += 1;
             }
             let p = p as *const u16;
-            let s = slice::from_raw_buf(&p, len as usize);
+            let s = slice::from_raw_parts(p, len as usize);
             self.cur = self.cur.offset(len + 1);
 
             let (k, v) = match s.iter().position(|&b| b == '=' as u16) {
@@ -296,7 +296,7 @@ impl Iterator for Args {
 
             // Push it onto the list.
             let ptr = ptr as *const u16;
-            let buf = slice::from_raw_buf(&ptr, len as usize);
+            let buf = slice::from_raw_parts(ptr, len as usize);
             OsStringExt::from_wide(buf)
         })
     }