about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-21 22:14:26 +0000
committerbors <bors@rust-lang.org>2020-05-21 22:14:26 +0000
commitd9417b385145af1cabd0be8a95c65075d2fc30ff (patch)
tree9a6348569c253000ec5edea9c6f15677687d26a7 /src/libcore
parent9310e3bd4f425f84fc27878ebf2bda1f30935a63 (diff)
parent74b5c50214c0edd9582d75fa472ed9a7ea25c0e5 (diff)
downloadrust-d9417b385145af1cabd0be8a95c65075d2fc30ff.tar.gz
rust-d9417b385145af1cabd0be8a95c65075d2fc30ff.zip
Auto merge of #72433 - RalfJung:rollup-srft8nx, r=RalfJung
Rollup of 7 pull requests

Successful merges:

 - #72055 (Intern predicates)
 - #72149 (Don't `type_of` on trait assoc ty without default)
 - #72347 (Make intra-link resolve links for both trait and impl items)
 - #72350 (Improve documentation of `slice::from_raw_parts`)
 - #72382 (Show default values for debug-assertions & debug-assertions-std)
 - #72421 (Fix anchor display when hovering impl)
 - #72425 (fix discriminant_value sign extension)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/slice/mod.rs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 9582ac33ff6..b5ce165cb43 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -5740,7 +5740,8 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 ///   and it must be properly aligned. This means in particular:
 ///
 ///     * The entire memory range of this slice must be contained within a single allocated object!
-///       Slices can never span across multiple allocated objects.
+///       Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
+///       for an example incorrectly not taking this into account.
 ///     * `data` must be non-null and aligned even for zero-length slices. One
 ///       reason for this is that enum layout optimizations may rely on references
 ///       (including slices of any length) being aligned and non-null to distinguish
@@ -5773,6 +5774,34 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 /// assert_eq!(slice[0], 42);
 /// ```
 ///
+/// ### Incorrect usage
+///
+/// The following `join_slices` function is **unsound** ⚠️
+///
+/// ```rust,no_run
+/// use std::slice;
+///
+/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
+///     let fst_end = fst.as_ptr().wrapping_add(fst.len());
+///     let snd_start = snd.as_ptr();
+///     assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
+///     unsafe {
+///         // The assertion above ensures `fst` and `snd` are contiguous, but they might
+///         // still be contained within _different allocated objects_, in which case
+///         // creating this slice is undefined behavior.
+///         slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
+///     }
+/// }
+///
+/// fn main() {
+///     // `a` and `b` are different allocated objects...
+///     let a = 42;
+///     let b = 27;
+///     // ... which may nevertheless be laid out contiguously in memory: | a | b |
+///     let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
+/// }
+/// ```
+///
 /// [valid]: ../../std/ptr/index.html#safety
 /// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
 /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset