Skip to content

Commit b75b21c

Browse files
committed
Auto merge of #21926 - mzabaluev:raw-lifetime, r=alexcrichton
New functions, `slice::from_raw_parts` and `slice::from_raw_parts_mut`, are added to implement the lifetime convention as agreed in rust-lang/rfcs#556. The functions `slice::from_raw_buf` and `slice::from_raw_mut_buf` are left deprecated for the time being. Holding back on changing the signature of `std::ffi::c_str_to_bytes` as consensus in rust-lang/rfcs#592 is building to replace it with a composition of other functions. Contribution to #21923.
2 parents 7884eb8 + fb6b970 commit b75b21c

File tree

10 files changed

+82
-32
lines changed

10 files changed

+82
-32
lines changed

src/libcollections/slice.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub use core::slice::{Iter, IterMut};
113113
pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split};
114114
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
115115
pub use core::slice::{bytes, mut_ref_slice, ref_slice};
116+
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
116117
pub use core::slice::{from_raw_buf, from_raw_mut_buf};
117118

118119
////////////////////////////////////////////////////////////////////////////////

src/libcore/slice.rs

+52-4
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,52 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
13571357
}
13581358
}
13591359

1360+
/// Forms a slice from a pointer and a length.
1361+
///
1362+
/// The `len` argument is the number of **elements**, not the number of bytes.
1363+
///
1364+
/// This function is unsafe as there is no guarantee that the given pointer is
1365+
/// valid for `len` elements, nor whether the lifetime inferred is a suitable
1366+
/// lifetime for the returned slice.
1367+
///
1368+
/// # Caveat
1369+
///
1370+
/// The lifetime for the returned slice is inferred from its usage. To
1371+
/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
1372+
/// source lifetime is safe in the context, such as by providing a helper
1373+
/// function taking the lifetime of a host value for the slice, or by explicit
1374+
/// annotation.
1375+
///
1376+
/// # Example
1377+
///
1378+
/// ```rust
1379+
/// use std::slice;
1380+
///
1381+
/// // manifest a slice out of thin air!
1382+
/// let ptr = 0x1234 as *const uint;
1383+
/// let amt = 10;
1384+
/// unsafe {
1385+
/// let slice = slice::from_raw_parts(ptr, amt);
1386+
/// }
1387+
/// ```
1388+
#[inline]
1389+
#[unstable(feature = "core")]
1390+
pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: uint) -> &'a [T] {
1391+
transmute(RawSlice { data: p, len: len })
1392+
}
1393+
1394+
/// Performs the same functionality as `from_raw_parts`, except that a mutable
1395+
/// slice is returned.
1396+
///
1397+
/// This function is unsafe for the same reasons as `from_raw_parts`, as well
1398+
/// as not being able to provide a non-aliasing guarantee of the returned
1399+
/// mutable slice.
1400+
#[inline]
1401+
#[unstable(feature = "core")]
1402+
pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: uint) -> &'a mut [T] {
1403+
transmute(RawSlice { data: p, len: len })
1404+
}
1405+
13601406
/// Forms a slice from a pointer and a length.
13611407
///
13621408
/// The pointer given is actually a reference to the base of the slice. This
@@ -1383,8 +1429,9 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
13831429
/// }
13841430
/// ```
13851431
#[inline]
1386-
#[unstable(feature = "core",
1387-
reason = "should be renamed to from_raw_parts")]
1432+
#[unstable(feature = "core")]
1433+
#[deprecated(since = "1.0.0",
1434+
reason = "use from_raw_parts")]
13881435
pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
13891436
transmute(RawSlice { data: *p, len: len })
13901437
}
@@ -1396,8 +1443,9 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
13961443
/// not being able to provide a non-aliasing guarantee of the returned mutable
13971444
/// slice.
13981445
#[inline]
1399-
#[unstable(feature = "core",
1400-
reason = "should be renamed to from_raw_parts_mut")]
1446+
#[unstable(feature = "core")]
1447+
#[deprecated(since = "1.0.0",
1448+
reason = "use from_raw_parts_mut")]
14011449
pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
14021450
transmute(RawSlice { data: *p, len: len })
14031451
}

src/libflate/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct Bytes {
4545
impl Deref for Bytes {
4646
type Target = [u8];
4747
fn deref(&self) -> &[u8] {
48-
unsafe { slice::from_raw_mut_buf(&self.ptr.0, self.len) }
48+
unsafe { slice::from_raw_parts_mut(self.ptr.0, self.len) }
4949
}
5050
}
5151

src/librand/isaac.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ impl Rand for IsaacRng {
246246
unsafe {
247247
let ptr = ret.rsl.as_mut_ptr() as *mut u8;
248248

249-
let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE * 4) as uint);
249+
let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE * 4) as uint);
250250
other.fill_bytes(slice);
251251
}
252252
ret.cnt = 0;
@@ -489,7 +489,7 @@ impl Rand for Isaac64Rng {
489489
unsafe {
490490
let ptr = ret.rsl.as_mut_ptr() as *mut u8;
491491

492-
let slice = slice::from_raw_mut_buf(&ptr, (RAND_SIZE_64 * 8) as uint);
492+
let slice = slice::from_raw_parts_mut(ptr, (RAND_SIZE_64 * 8) as uint);
493493
other.fill_bytes(slice);
494494
}
495495
ret.cnt = 0;

src/librustc/metadata/loader.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,8 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
744744
while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
745745
let mut name_buf = ptr::null();
746746
let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
747-
let name = slice::from_raw_buf(&(name_buf as *const u8),
748-
name_len as uint).to_vec();
747+
let name = slice::from_raw_parts(name_buf as *const u8,
748+
name_len as uint).to_vec();
749749
let name = String::from_utf8(name).unwrap();
750750
debug!("get_metadata_section: name {}", name);
751751
if read_meta_section_name(is_osx) == name {
@@ -756,7 +756,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
756756
debug!("checking {} bytes of metadata-version stamp",
757757
vlen);
758758
let minsz = cmp::min(vlen, csz);
759-
let buf0 = slice::from_raw_buf(&cvbuf, minsz);
759+
let buf0 = slice::from_raw_parts(cvbuf, minsz);
760760
let version_ok = buf0 == encoder::metadata_encoding_version;
761761
if !version_ok {
762762
return Err((format!("incompatible metadata version found: '{}'",
@@ -766,7 +766,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
766766
let cvbuf1 = cvbuf.offset(vlen as int);
767767
debug!("inflating {} bytes of compressed metadata",
768768
csz - vlen);
769-
let bytes = slice::from_raw_buf(&cvbuf1, csz-vlen);
769+
let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
770770
match flate::inflate_bytes(bytes) {
771771
Some(inflated) => return Ok(MetadataVec(inflated)),
772772
None => {}

src/librustdoc/html/markdown.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ extern {
165165

166166
}
167167

168+
// hoedown_buffer helpers
169+
impl hoedown_buffer {
170+
fn as_bytes(&self) -> &[u8] {
171+
unsafe { slice::from_raw_parts(self.data, self.size as usize) }
172+
}
173+
}
174+
168175
/// Returns Some(code) if `s` is a line that should be stripped from
169176
/// documentation but used in example code. `code` is the portion of
170177
/// `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 {
194201

195202
let opaque = opaque as *mut hoedown_html_renderer_state;
196203
let my_opaque: &MyOpaque = &*((*opaque).opaque as *const MyOpaque);
197-
let text = slice::from_raw_buf(&(*orig_text).data,
198-
(*orig_text).size as uint);
204+
let text = (*orig_text).as_bytes();
199205
let origtext = str::from_utf8(text).unwrap();
200206
debug!("docblock: ==============\n{:?}\n=======", text);
201207
let rendered = if lang.is_null() {
202208
false
203209
} else {
204-
let rlang = slice::from_raw_buf(&(*lang).data,
205-
(*lang).size as uint);
210+
let rlang = (*lang).as_bytes();
206211
let rlang = str::from_utf8(rlang).unwrap();
207212
if !LangString::parse(rlang).rust {
208213
(my_opaque.dfltblk)(ob, orig_text, lang,
@@ -246,9 +251,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
246251
let s = if text.is_null() {
247252
"".to_string()
248253
} else {
249-
let s = unsafe {
250-
slice::from_raw_buf(&(*text).data, (*text).size as uint)
251-
};
254+
let s = unsafe { (*text).as_bytes() };
252255
str::from_utf8(s).unwrap().to_string()
253256
};
254257

@@ -321,7 +324,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
321324
};
322325

323326
if ret.is_ok() {
324-
let buf = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
327+
let buf = (*ob).as_bytes();
325328
ret = w.write_str(str::from_utf8(buf).unwrap());
326329
}
327330
hoedown_buffer_free(ob);
@@ -339,13 +342,12 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
339342
let block_info = if lang.is_null() {
340343
LangString::all_false()
341344
} else {
342-
let lang = slice::from_raw_buf(&(*lang).data,
343-
(*lang).size as uint);
345+
let lang = (*lang).as_bytes();
344346
let s = str::from_utf8(lang).unwrap();
345347
LangString::parse(s)
346348
};
347349
if !block_info.rust { return }
348-
let text = slice::from_raw_buf(&(*text).data, (*text).size as uint);
350+
let text = (*text).as_bytes();
349351
let opaque = opaque as *mut hoedown_html_renderer_state;
350352
let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
351353
let text = str::from_utf8(text).unwrap();
@@ -368,7 +370,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
368370
if text.is_null() {
369371
tests.register_header("", level as u32);
370372
} else {
371-
let text = slice::from_raw_buf(&(*text).data, (*text).size as uint);
373+
let text = (*text).as_bytes();
372374
let text = str::from_utf8(text).unwrap();
373375
tests.register_header(text, level as u32);
374376
}
@@ -508,7 +510,7 @@ pub fn plain_summary_line(md: &str) -> String {
508510
hoedown_document_render(document, ob, md.as_ptr(),
509511
md.len() as libc::size_t);
510512
hoedown_document_free(document);
511-
let plain_slice = slice::from_raw_buf(&(*ob).data, (*ob).size as uint);
513+
let plain_slice = (*ob).as_bytes();
512514
let plain = match str::from_utf8(plain_slice) {
513515
Ok(s) => s.to_string(),
514516
Err(_) => "".to_string(),

src/libstd/ffi/c_str.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl fmt::Debug for CString {
162162
/// ```
163163
pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
164164
let len = libc::strlen(*raw);
165-
slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
165+
slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
166166
}
167167

168168
/// 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] {
171171
/// will include the nul terminator of the string.
172172
pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
173173
let len = libc::strlen(*raw) + 1;
174-
slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
174+
slice::from_raw_parts(*(raw as *const _ as *const *const u8), len as usize)
175175
}
176176

177177
#[cfg(test)]

src/libstd/io/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use error::Error as StdError;
2424
use fmt;
2525
use iter::Iterator;
2626
use marker::Sized;
27-
use mem;
2827
use ops::{Drop, FnOnce};
2928
use option::Option::{self, Some, None};
3029
use ptr::PtrExt;
@@ -69,8 +68,8 @@ fn with_end_to_cap<F>(v: &mut Vec<u8>, f: F) -> Result<usize>
6968
unsafe {
7069
let n = try!(f({
7170
let base = v.as_mut_ptr().offset(v.len() as isize);
72-
black_box(slice::from_raw_mut_buf(mem::copy_lifetime(v, &base),
73-
v.capacity() - v.len()))
71+
black_box(slice::from_raw_parts_mut(base,
72+
v.capacity() - v.len()))
7473
}));
7574

7675
// If the closure (typically a `read` implementation) reported that it

src/libstd/os.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ fn real_args() -> Vec<String> {
671671

672672
// Push it onto the list.
673673
let ptr = ptr as *const u16;
674-
let buf = slice::from_raw_buf(&ptr, len);
674+
let buf = slice::from_raw_parts(ptr, len);
675675
let opt_s = String::from_utf16(sys::truncate_utf16_at_nul(buf));
676676
opt_s.ok().expect("CommandLineToArgvW returned invalid UTF-16")
677677
}).collect();

src/libstd/sys/windows/os.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl Iterator for Env {
109109
len += 1;
110110
}
111111
let p = p as *const u16;
112-
let s = slice::from_raw_buf(&p, len as usize);
112+
let s = slice::from_raw_parts(p, len as usize);
113113
self.cur = self.cur.offset(len + 1);
114114

115115
let (k, v) = match s.iter().position(|&b| b == '=' as u16) {
@@ -296,7 +296,7 @@ impl Iterator for Args {
296296

297297
// Push it onto the list.
298298
let ptr = ptr as *const u16;
299-
let buf = slice::from_raw_buf(&ptr, len as usize);
299+
let buf = slice::from_raw_parts(ptr, len as usize);
300300
OsStringExt::from_wide(buf)
301301
})
302302
}

0 commit comments

Comments
 (0)