Skip to content

Commit 088c994

Browse files
authored
Rollup merge of rust-lang#60443 - RalfJung:as_ptr, r=SimonSapin
as_ptr returns a read-only pointer Add comments to `as_ptr` methods to warn that these are read-only pointers, and writing to them is UB. [It was pointed out](https://internals.rust-lang.org/t/as-ptr-vs-as-mut-ptr/9940) that `CStr` does not even have an `as_mut_ptr`. I originally was going to add one, but there is no method at all that would mutate a `CStr`. Was that a deliberate choice or should I add an `as_mut_ptr` (similar to [what I did for `str`](rust-lang#58200))?
2 parents bab03ce + 30cf0e4 commit 088c994

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

src/libcore/slice/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ impl<T> [T] {
359359
/// The caller must ensure that the slice outlives the pointer this
360360
/// function returns, or else it will end up pointing to garbage.
361361
///
362+
/// The caller must also ensure that the memory the pointer (non-transitively) points to
363+
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
364+
/// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
365+
///
362366
/// Modifying the container referenced by this slice may cause its buffer
363367
/// to be reallocated, which would also make any pointers to it invalid.
364368
///
@@ -374,6 +378,8 @@ impl<T> [T] {
374378
/// }
375379
/// }
376380
/// ```
381+
///
382+
/// [`as_mut_ptr`]: #method.as_mut_ptr
377383
#[stable(feature = "rust1", since = "1.0.0")]
378384
#[inline]
379385
pub const fn as_ptr(&self) -> *const T {

src/libcore/str/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,7 +2198,11 @@ impl str {
21982198
/// [`u8`]. This pointer will be pointing to the first byte of the string
21992199
/// slice.
22002200
///
2201+
/// The caller must ensure that the returned pointer is never written to.
2202+
/// If you need to mutate the contents of the string slice, use [`as_mut_ptr`].
2203+
///
22012204
/// [`u8`]: primitive.u8.html
2205+
/// [`as_mut_ptr`]: #method.as_mut_ptr
22022206
///
22032207
/// # Examples
22042208
///

src/libstd/ffi/c_str.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ use crate::sys;
4343
/// `CString` implements a [`as_ptr`] method through the [`Deref`]
4444
/// trait. This method will give you a `*const c_char` which you can
4545
/// feed directly to extern functions that expect a nul-terminated
46-
/// string, like C's `strdup()`.
46+
/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
47+
/// read-only pointer; if the C code writes to it, that causes
48+
/// undefined behavior.
4749
///
4850
/// # Extracting a slice of the whole C string
4951
///
@@ -61,7 +63,7 @@ use crate::sys;
6163
///
6264
/// Once you have the kind of slice you need (with or without a nul
6365
/// terminator), you can call the slice's own
64-
/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to
66+
/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to
6567
/// extern functions. See the documentation for that function for a
6668
/// discussion on ensuring the lifetime of the raw pointer.
6769
///
@@ -1043,6 +1045,9 @@ impl CStr {
10431045
///
10441046
/// **WARNING**
10451047
///
1048+
/// The returned pointer is read-only; writing to it (including passing it
1049+
/// to C code that writes to it) causes undefined behavior.
1050+
///
10461051
/// It is your responsibility to make sure that the underlying memory is not
10471052
/// freed too early. For example, the following code will cause undefined
10481053
/// behavior when `ptr` is used inside the `unsafe` block:

0 commit comments

Comments
 (0)