From 1e47250540bc97f921d1b7e2982f1904fa191dff Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 1 May 2019 17:59:48 +0200
Subject: [PATCH 1/2] as_ptr returns a read-only pointer

---
 src/libcore/slice/mod.rs | 6 ++++++
 src/libcore/str/mod.rs   | 5 +++++
 src/libstd/ffi/c_str.rs  | 9 +++++++--
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 8731f48675356..c273153fa5ead 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -359,6 +359,10 @@ impl<T> [T] {
     /// The caller must ensure that the slice outlives the pointer this
     /// function returns, or else it will end up pointing to garbage.
     ///
+    /// The caller must also ensure that the memory the pointer (non-transitively) points to
+    /// is never written to (except inside an `UnsafeCell`). If you need to mutate
+    /// the contents of the slice, use [`as_mut_ptr`].
+    ///
     /// Modifying the container referenced by this slice may cause its buffer
     /// to be reallocated, which would also make any pointers to it invalid.
     ///
@@ -374,6 +378,8 @@ impl<T> [T] {
     ///     }
     /// }
     /// ```
+    ///
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub const fn as_ptr(&self) -> *const T {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 45421848cec5d..96a5ce61ca0bc 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2188,7 +2188,12 @@ impl str {
     /// [`u8`]. This pointer will be pointing to the first byte of the string
     /// slice.
     ///
+    /// The caller must ensure that the memory the pointer points to
+    /// is never written to. If you need to mutate
+    /// the contents of the string slice, use [`as_mut_ptr`].
+    ///
     /// [`u8`]: primitive.u8.html
+    /// [`as_mut_ptr`]: #method.as_mut_ptr
     ///
     /// # Examples
     ///
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index f93583dff818f..5c6c43017cf64 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -43,7 +43,9 @@ use crate::sys;
 /// `CString` implements a [`as_ptr`] method through the [`Deref`]
 /// trait. This method will give you a `*const c_char` which you can
 /// feed directly to extern functions that expect a nul-terminated
-/// string, like C's `strdup()`.
+/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
+/// read-only pointer; if the C code writes to it, that causes
+/// undefined behavior.
 ///
 /// # Extracting a slice of the whole C string
 ///
@@ -61,7 +63,7 @@ use crate::sys;
 ///
 /// Once you have the kind of slice you need (with or without a nul
 /// terminator), you can call the slice's own
-/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to
+/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to
 /// extern functions. See the documentation for that function for a
 /// discussion on ensuring the lifetime of the raw pointer.
 ///
@@ -1043,6 +1045,9 @@ impl CStr {
     ///
     /// **WARNING**
     ///
+    /// The returned pointer is read-only; writing to it (including passing it
+    /// to C code that writes to it) causes undefined behavior.
+    ///
     /// It is your responsibility to make sure that the underlying memory is not
     /// freed too early. For example, the following code will cause undefined
     /// behavior when `ptr` is used inside the `unsafe` block:

From 30cf0e4251533e67603c755acee5b0bd56197fce Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 2 May 2019 13:36:30 +0200
Subject: [PATCH 2/2] clarify wording

---
 src/libcore/slice/mod.rs | 4 ++--
 src/libcore/str/mod.rs   | 5 ++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index c273153fa5ead..50d2ba0d3ef7f 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -360,8 +360,8 @@ impl<T> [T] {
     /// function returns, or else it will end up pointing to garbage.
     ///
     /// The caller must also ensure that the memory the pointer (non-transitively) points to
-    /// is never written to (except inside an `UnsafeCell`). If you need to mutate
-    /// the contents of the slice, use [`as_mut_ptr`].
+    /// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
+    /// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
     ///
     /// Modifying the container referenced by this slice may cause its buffer
     /// to be reallocated, which would also make any pointers to it invalid.
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 96a5ce61ca0bc..ef4bd83cbc5a6 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2188,9 +2188,8 @@ impl str {
     /// [`u8`]. This pointer will be pointing to the first byte of the string
     /// slice.
     ///
-    /// The caller must ensure that the memory the pointer points to
-    /// is never written to. If you need to mutate
-    /// the contents of the string slice, use [`as_mut_ptr`].
+    /// The caller must ensure that the returned pointer is never written to.
+    /// If you need to mutate the contents of the string slice, use [`as_mut_ptr`].
     ///
     /// [`u8`]: primitive.u8.html
     /// [`as_mut_ptr`]: #method.as_mut_ptr