Skip to content

Commit 641e2a1

Browse files
committed
auto merge of #19152 : alexcrichton/rust/issue-17863, r=aturon
This commit is an implementation of [RFC 240][rfc] when applied to the standard library. It primarily deprecates the entirety of `string::raw`, `vec::raw`, `slice::raw`, and `str::raw` in favor of associated functions, methods, and other free functions. The detailed renaming is: * slice::raw::buf_as_slice => slice::from_raw_buf * slice::raw::mut_buf_as_slice => slice::from_raw_mut_buf * slice::shift_ptr => deprecated with no replacement * slice::pop_ptr => deprecated with no replacement * str::raw::from_utf8 => str::from_utf8_unchecked * str::raw::c_str_to_static_slice => str::from_c_str * str::raw::slice_bytes => deprecated for slice_unchecked (slight semantic diff) * str::raw::slice_unchecked => str.slice_unchecked * string::raw::from_parts => String::from_raw_parts * string::raw::from_buf_len => String::from_raw_buf_len * string::raw::from_buf => String::from_raw_buf * string::raw::from_utf8 => String::from_utf8_unchecked * vec::raw::from_buf => Vec::from_raw_buf All previous functions exist in their `#[deprecated]` form, and the deprecation messages indicate how to migrate to the newer variants. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0240-unsafe-api-location.md [breaking-change] Closes #17863
2 parents 529f8bc + 8ca27a6 commit 641e2a1

File tree

15 files changed

+304
-208
lines changed

15 files changed

+304
-208
lines changed

src/libcollections/slice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ pub use core::slice::{OrdSlicePrelude, SlicePrelude, Items, MutItems};
106106
pub use core::slice::{ImmutableIntSlice, MutableIntSlice};
107107
pub use core::slice::{MutSplits, MutChunks, Splits};
108108
pub use core::slice::{bytes, mut_ref_slice, ref_slice, CloneSlicePrelude};
109-
pub use core::slice::{Found, NotFound};
109+
pub use core::slice::{Found, NotFound, from_raw_buf, from_raw_mut_buf};
110110

111111
// Functional utilities
112112

src/libcollections/str.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
8080
pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
8181
pub use core::str::{FromStr, from_str};
8282
pub use core::str::{Str, StrPrelude};
83+
pub use core::str::{from_utf8_unchecked, from_c_str};
8384
pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices};
8485

8586
// FIXME(conventions): ensure bit/char conventions are followed by str's API
@@ -393,11 +394,11 @@ pub fn replace(s: &str, from: &str, to: &str) -> String {
393394
let mut result = String::new();
394395
let mut last_end = 0;
395396
for (start, end) in s.match_indices(from) {
396-
result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
397+
result.push_str(unsafe { s.slice_unchecked(last_end, start) });
397398
result.push_str(to);
398399
last_end = end;
399400
}
400-
result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
401+
result.push_str(unsafe { s.slice_unchecked(last_end, s.len()) });
401402
result
402403
}
403404

@@ -674,16 +675,7 @@ pub trait StrAllocating: Str {
674675
/// assert_eq!(s.replace("cookie monster", "little lamb"), s);
675676
/// ```
676677
fn replace(&self, from: &str, to: &str) -> String {
677-
let me = self.as_slice();
678-
let mut result = String::new();
679-
let mut last_end = 0;
680-
for (start, end) in me.match_indices(from) {
681-
result.push_str(unsafe{raw::slice_bytes(me, last_end, start)});
682-
result.push_str(to);
683-
last_end = end;
684-
}
685-
result.push_str(unsafe{raw::slice_bytes(me, last_end, me.len())});
686-
result
678+
replace(self.as_slice(), from, to)
687679
}
688680

689681
/// Given a string, makes a new string with repeated copies of it.

src/libcollections/string.rs

+56-20
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,52 @@ impl String {
297297
chs.iter().map(|c| *c).collect()
298298
}
299299

300+
/// Creates a new `String` from a length, capacity, and pointer.
301+
///
302+
/// This is unsafe because:
303+
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
304+
/// * We assume that the `Vec` contains valid UTF-8.
305+
#[inline]
306+
#[unstable = "function just moved from string::raw"]
307+
pub unsafe fn from_raw_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
308+
String {
309+
vec: Vec::from_raw_parts(buf, length, capacity),
310+
}
311+
}
312+
313+
/// Creates a `String` from a null-terminated `*const u8` buffer.
314+
///
315+
/// This function is unsafe because we dereference memory until we find the
316+
/// NUL character, which is not guaranteed to be present. Additionally, the
317+
/// slice is not checked to see whether it contains valid UTF-8
318+
#[unstable = "just renamed from `mod raw`"]
319+
pub unsafe fn from_raw_buf(buf: *const u8) -> String {
320+
String::from_str(str::from_c_str(buf as *const i8))
321+
}
322+
323+
/// Creates a `String` from a `*const u8` buffer of the given length.
324+
///
325+
/// This function is unsafe because it blindly assumes the validity of the
326+
/// pointer `buf` for `len` bytes of memory. This function will copy the
327+
/// memory from `buf` into a new allocation (owned by the returned
328+
/// `String`).
329+
///
330+
/// This function is also unsafe because it does not validate that the
331+
/// buffer is valid UTF-8 encoded data.
332+
#[unstable = "just renamed from `mod raw`"]
333+
pub unsafe fn from_raw_buf_len(buf: *const u8, len: uint) -> String {
334+
String::from_utf8_unchecked(Vec::from_raw_buf(buf, len))
335+
}
336+
337+
/// Converts a vector of bytes to a new `String` without checking if
338+
/// it contains valid UTF-8. This is unsafe because it assumes that
339+
/// the UTF-8-ness of the vector has already been validated.
340+
#[inline]
341+
#[unstable = "awaiting stabilization"]
342+
pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
343+
String { vec: bytes }
344+
}
345+
300346
/// Return the underlying byte buffer, encoded as UTF-8.
301347
///
302348
/// # Example
@@ -823,12 +869,8 @@ impl<T: fmt::Show> ToString for T {
823869
}
824870

825871
/// Unsafe operations
826-
#[unstable = "waiting on raw module conventions"]
872+
#[deprecated]
827873
pub mod raw {
828-
use core::mem;
829-
use core::ptr::RawPtr;
830-
use core::raw::Slice;
831-
832874
use super::String;
833875
use vec::Vec;
834876

@@ -838,45 +880,39 @@ pub mod raw {
838880
/// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
839881
/// * We assume that the `Vec` contains valid UTF-8.
840882
#[inline]
883+
#[deprecated = "renamed to String::from_raw_parts"]
841884
pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
842-
String {
843-
vec: Vec::from_raw_parts(buf, length, capacity),
844-
}
885+
String::from_raw_parts(buf, length, capacity)
845886
}
846887

847888
/// Creates a `String` from a `*const u8` buffer of the given length.
848889
///
849890
/// This function is unsafe because of two reasons:
891+
///
850892
/// * A raw pointer is dereferenced and transmuted to `&[u8]`;
851893
/// * The slice is not checked to see whether it contains valid UTF-8.
894+
#[deprecated = "renamed to String::from_raw_buf_len"]
852895
pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
853-
use slice::CloneSliceAllocPrelude;
854-
let slice: &[u8] = mem::transmute(Slice {
855-
data: buf,
856-
len: len,
857-
});
858-
self::from_utf8(slice.to_vec())
896+
String::from_raw_buf_len(buf, len)
859897
}
860898

861899
/// Creates a `String` from a null-terminated `*const u8` buffer.
862900
///
863901
/// This function is unsafe because we dereference memory until we find the NUL character,
864902
/// which is not guaranteed to be present. Additionally, the slice is not checked to see
865903
/// whether it contains valid UTF-8
904+
#[deprecated = "renamed to String::from_raw_buf"]
866905
pub unsafe fn from_buf(buf: *const u8) -> String {
867-
let mut len = 0;
868-
while *buf.offset(len) != 0 {
869-
len += 1;
870-
}
871-
self::from_buf_len(buf, len as uint)
906+
String::from_raw_buf(buf)
872907
}
873908

874909
/// Converts a vector of bytes to a new `String` without checking if
875910
/// it contains valid UTF-8. This is unsafe because it assumes that
876911
/// the UTF-8-ness of the vector has already been validated.
877912
#[inline]
913+
#[deprecated = "renamed to String::from_utf8_unchecked"]
878914
pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
879-
String { vec: bytes }
915+
String::from_utf8_unchecked(bytes)
880916
}
881917
}
882918

src/libcollections/vec.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,27 @@ impl<T> Vec<T> {
235235
/// }
236236
/// }
237237
/// ```
238-
#[experimental]
238+
#[unstable = "needs finalization"]
239239
pub unsafe fn from_raw_parts(ptr: *mut T, length: uint,
240240
capacity: uint) -> Vec<T> {
241241
Vec { ptr: ptr, len: length, cap: capacity }
242242
}
243243

244+
/// Creates a vector by copying the elements from a raw pointer.
245+
///
246+
/// This function will copy `elts` contiguous elements starting at `ptr`
247+
/// into a new allocation owned by the returned `Vec`. The elements of the
248+
/// buffer are copied into the vector without cloning, as if `ptr::read()`
249+
/// were called on them.
250+
#[inline]
251+
#[unstable = "just renamed from raw::from_buf"]
252+
pub unsafe fn from_raw_buf(ptr: *const T, elts: uint) -> Vec<T> {
253+
let mut dst = Vec::with_capacity(elts);
254+
dst.set_len(elts);
255+
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
256+
dst
257+
}
258+
244259
/// Consumes the `Vec`, partitioning it based on a predicate.
245260
///
246261
/// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
@@ -1367,23 +1382,18 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
13671382
}
13681383

13691384
/// Unsafe vector operations.
1370-
#[unstable]
1385+
#[deprecated]
13711386
pub mod raw {
13721387
use super::Vec;
1373-
use core::ptr;
1374-
use core::slice::SlicePrelude;
13751388

13761389
/// Constructs a vector from an unsafe pointer to a buffer.
13771390
///
13781391
/// The elements of the buffer are copied into the vector without cloning,
13791392
/// as if `ptr::read()` were called on them.
13801393
#[inline]
1381-
#[unstable]
1394+
#[deprecated = "renamed to Vec::from_raw_buf"]
13821395
pub unsafe fn from_buf<T>(ptr: *const T, elts: uint) -> Vec<T> {
1383-
let mut dst = Vec::with_capacity(elts);
1384-
dst.set_len(elts);
1385-
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
1386-
dst
1396+
Vec::from_raw_buf(ptr, elts)
13871397
}
13881398
}
13891399

src/libcore/slice.rs

+47-3
Original file line numberDiff line numberDiff line change
@@ -1559,15 +1559,55 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
15591559
}
15601560
}
15611561

1562+
/// Forms a slice from a pointer and a length.
1563+
///
1564+
/// The pointer given is actually a reference to the base of the slice. This
1565+
/// reference is used to give a concrete lifetime to tie the returned slice to.
1566+
/// Typically this should indicate that the slice is valid for as long as the
1567+
/// pointer itself is valid.
1568+
///
1569+
/// The `len` argument is the number of **elements**, not the number of bytes.
1570+
///
1571+
/// This function is unsafe as there is no guarantee that the given pointer is
1572+
/// valid for `len` elements, nor whether the lifetime provided is a suitable
1573+
/// lifetime for the returned slice.
1574+
///
1575+
/// # Example
1576+
///
1577+
/// ```rust
1578+
/// use std::slice;
1579+
///
1580+
/// // manifest a slice out of thin air!
1581+
/// let ptr = 0x1234 as *const uint;
1582+
/// let amt = 10;
1583+
/// unsafe {
1584+
/// let slice = slice::from_raw_buf(&ptr, amt);
1585+
/// }
1586+
/// ```
1587+
#[inline]
1588+
#[unstable = "just renamed from `mod raw`"]
1589+
pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
1590+
transmute(RawSlice { data: *p, len: len })
1591+
}
15621592

1563-
1593+
/// Performs the same functionality as `from_raw_buf`, except that a mutable
1594+
/// slice is returned.
1595+
///
1596+
/// This function is unsafe for the same reasons as `from_raw_buf`, as well as
1597+
/// not being able to provide a non-aliasing guarantee of the returned mutable
1598+
/// slice.
1599+
#[inline]
1600+
#[unstable = "just renamed from `mod raw`"]
1601+
pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
1602+
transmute(RawSlice { data: *p as *const T, len: len })
1603+
}
15641604

15651605
//
15661606
// Submodules
15671607
//
15681608

15691609
/// Unsafe operations
1570-
#[experimental = "needs review"]
1610+
#[deprecated]
15711611
pub mod raw {
15721612
use mem::transmute;
15731613
use ptr::RawPtr;
@@ -1579,6 +1619,7 @@ pub mod raw {
15791619
* not bytes).
15801620
*/
15811621
#[inline]
1622+
#[deprecated = "renamed to slice::from_raw_buf"]
15821623
pub unsafe fn buf_as_slice<T,U>(p: *const T, len: uint, f: |v: &[T]| -> U)
15831624
-> U {
15841625
f(transmute(Slice {
@@ -1592,6 +1633,7 @@ pub mod raw {
15921633
* not bytes).
15931634
*/
15941635
#[inline]
1636+
#[deprecated = "renamed to slice::from_raw_mut_buf"]
15951637
pub unsafe fn mut_buf_as_slice<T,
15961638
U>(
15971639
p: *mut T,
@@ -1610,6 +1652,7 @@ pub mod raw {
16101652
* if the slice is empty. O(1).
16111653
*/
16121654
#[inline]
1655+
#[deprecated = "inspect `Slice::{data, len}` manually (increment data by 1)"]
16131656
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
16141657
if slice.len == 0 { return None; }
16151658
let head: *const T = slice.data;
@@ -1623,7 +1666,8 @@ pub mod raw {
16231666
* slice so it no longer contains that element. Returns None
16241667
* if the slice is empty. O(1).
16251668
*/
1626-
#[inline]
1669+
#[inline]
1670+
#[deprecated = "inspect `Slice::{data, len}` manually (decrement len by 1)"]
16271671
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> Option<*const T> {
16281672
if slice.len == 0 { return None; }
16291673
let tail: *const T = slice.data.offset((slice.len - 1) as int);

0 commit comments

Comments
 (0)