From de9b660a40728d4c4213f2ec7a1c99a9bc352023 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 25 Oct 2019 15:21:00 +0200 Subject: [PATCH] Explain why pointer::add in slice::as_ptr_range is safe. --- src/libcore/slice/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0a115ce84ca..185913a47f1 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -437,6 +437,23 @@ impl [T] { #[unstable(feature = "slice_ptr_range", issue = "65807")] #[inline] pub fn as_ptr_range(&self) -> Range<*const T> { + // The `add` here is safe, because: + // + // - Both pointers are part of the same object, as pointing directly + // past the object also counts. + // + // - The size of the slice is never larger than isize::MAX bytes, as + // noted here: + // - https://github.com/rust-lang/unsafe-code-guidelines/issues/102#issuecomment-473340447 + // - https://doc.rust-lang.org/reference/behavior-considered-undefined.html + // - https://doc.rust-lang.org/core/slice/fn.from_raw_parts.html#safety + // (This doesn't seem normative yet, but the very same assumption is + // made in many places, including the Index implementation of slices.) + // + // - There is no wrapping around involved, as slices do not wrap past + // the end of the address space. + // + // See the documentation of pointer::add. let start = self.as_ptr(); let end = unsafe { start.add(self.len()) }; start..end @@ -461,6 +478,7 @@ impl [T] { #[unstable(feature = "slice_ptr_range", issue = "65807")] #[inline] pub fn as_mut_ptr_range(&mut self) -> Range<*mut T> { + // See as_ptr_range() above for why `add` here is safe. let start = self.as_mut_ptr(); let end = unsafe { start.add(self.len()) }; start..end