Squashed 'third_party/flatbuffers/' changes from bc44fad35..8aa8b9139

8aa8b9139 Fix handling of +/-inf defaults in TS/rust/go/dart codegen (#7588)
001adf782 Add support for parsing proto map fields (#7613)
dbc58ab77 Fix help output for --gen-includes (#7611)
2facfeec7 Fix missing spaces in flatc help text (#7612)
4de2814c7 Fix: arduino platform build (#7625)
37b1acdaf Fix current official name of macOS (#7627)
a22434e2a Add missing #include <algorithm> for std::min/std::max uses, and #include <limits> for std::numeric_limits<> (#7624)
214cc9468 Bump Rust version to 22.10.26 before publication (#7622)
a4ff275d9 Added option to not requires an EoF token when parsing JSON (#7620)
15f32c690 python: object generation prefix and suffix (#7565)
051afd882 Add CreateSharedString to python builder (#7608)
728c033ad Add check for presence of realpath to CMakeLists.txt to support more platforms (#7603)
4c514483d Update DartTest.sh golden files (#7606)
c2d9c2080 [TS] Add support for fixed length arrays on Typescript (#5864) (#7021) (#7581)
e34ae4c6b `build.yml`: Fix missing 'v' in version
e54536127 `build.yml` Update to Kotlin Wrapper 1.0.5
49d9f941c `release.yml` Use env var for passphrase
cefc21c1f `release.yml` Add GPG key for Maven
3e64fa724 `release.yml`: Add Maven Steps
b15f3c57e `release_yml` Use new dotnet version
ff802c680 `release.yml` Use NuGet Key directly
b401957d5 `release.yml` Changed Push to follow examples
8c8151f8f `release.yml` Fix nuget push command
ebb7c203d `release.yml` Add Nuget support
203241ed3 FlatBuffers Version 22.10.26 (#7607)
ac485609c `setup.py`: Define version directly
de5b85aa6 `release.yml`: Switch to `python` directory
de3df2d88 `release.yml`: Add publishing to PyPi
043a24f2e [Python] Fixed the issue with nested unions relying on InitFromBuf. (#7576)
5a48b0d7d release.yml: Typo
ce307556f release.yml: Remove `npm ci`
cb616e27c Create release.yml (#7605)
a54ca1e75 FlatBuffers Version 22.10.25 (#7604)
5b3fadcc1 [vector] Allow to iterate with mutables (#7586)
872a49746 [Nim] Bfbs Nim Generator (#7534)
e30170296 Make type conversions explicit. (#7595)
f7b734438 Fix LongEnum definitions (#7596)
5792623df Rust fix compilation for no_std targets #2 (#7553)
0edb27528 Update Rust version (#7574)
acc6a20d3 tests/test.cpp contains a couple of tests that are only executed (#7571)
04cd037ba Fix #7580 by documenting union schema evolution rules (#7585)
e1c5db988 Turn on clippy for Rust and fix lints for non-generated code (#7575)
b80142b90 Update documentation to mention enum value attributes (#7570)
54418f371 Add support for metadata attributes for enum values (#7567) (#7568)
c92e78a9f FlatBuffers Version 22.9.29 (#7557)
d243b904c [TS] Make strict compliant and improve typings (#7549)
374f8fb5f Rust soundness fixes (#7518)
dadbff571 Moves swift package to root of repository so it can be used directly … (#7548)
76ddae006 FlatBuffers Version 22.9.24 (#7547)
cfe157ec5 Emit internal enums when swift_implementation_only (#7545)
413115858 [Python] Python fixed size array (#7529)
88046190e Upgrade grpc to 1.49.0 and make sure it builds (#7538)
72aa85a75 [C++] Rare bad buffer content alignment if sizeof(T) != alignof(T) (#7520)
bfceebb7f Fix conform (#7532)

git-subtree-dir: third_party/flatbuffers
git-subtree-split: 8aa8b9139eb330f27816a5b8b5bbef402fbe3632
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
Change-Id: I943faba499baf58e9f561b1e4734922188ba8626
diff --git a/rust/flatbuffers/src/vector.rs b/rust/flatbuffers/src/vector.rs
index da04ef6..b486ff3 100644
--- a/rust/flatbuffers/src/vector.rs
+++ b/rust/flatbuffers/src/vector.rs
@@ -17,13 +17,10 @@
 use core::fmt::{Debug, Formatter, Result};
 use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
 use core::marker::PhantomData;
-use core::mem::size_of;
-use core::slice::from_raw_parts;
+use core::mem::{align_of, size_of};
 use core::str::from_utf8_unchecked;
 
 use crate::endian_scalar::read_scalar_at;
-#[cfg(target_endian = "little")]
-use crate::endian_scalar::EndianScalar;
 use crate::follow::Follow;
 use crate::primitives::*;
 
@@ -55,6 +52,7 @@
 // and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
 // can always be copied, no matter that `T` you have.
 impl<'a, T> Copy for Vector<'a, T> {}
+
 impl<'a, T> Clone for Vector<'a, T> {
     fn clone(&self) -> Self {
         *self
@@ -62,32 +60,46 @@
 }
 
 impl<'a, T: 'a> Vector<'a, T> {
+    /// # Safety
+    ///
+    /// `buf` contains a valid vector at `loc` consisting of
+    ///
+    /// - UOffsetT element count
+    /// - Consecutive list of `T` elements
     #[inline(always)]
-    pub fn new(buf: &'a [u8], loc: usize) -> Self {
-        Vector {
-            0: buf,
-            1: loc,
-            2: PhantomData,
-        }
+    pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
+        Vector(buf, loc, PhantomData)
     }
 
     #[inline(always)]
     pub fn len(&self) -> usize {
+        // Safety:
+        // Valid vector at time of construction starting with UOffsetT element count
         unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
     }
+
     #[inline(always)]
     pub fn is_empty(&self) -> bool {
         self.len() == 0
     }
+
+    #[inline(always)]
+    pub fn bytes(&self) -> &'a [u8] {
+        let sz = size_of::<T>();
+        let len = self.len();
+        &self.0[self.1 + SIZE_UOFFSET..self.1 + SIZE_UOFFSET + sz * len]
+    }
 }
 
 impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
     #[inline(always)]
     pub fn get(&self, idx: usize) -> T::Inner {
-        assert!(idx < self.len() as usize);
+        assert!(idx < self.len());
         let sz = size_of::<T>();
         debug_assert!(sz > 0);
-        T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx)
+        // Safety:
+        // Valid vector at time of construction, verified that idx < element count
+        unsafe { T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) }
     }
 
     #[inline(always)]
@@ -96,84 +108,40 @@
     }
 }
 
-pub trait SafeSliceAccess {}
-impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
-    pub fn safe_slice(self) -> &'a [T] {
-        let buf = self.0;
-        let loc = self.1;
-        let sz = size_of::<T>();
-        debug_assert!(sz > 0);
-        let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
-        let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
-        let ptr = data_buf.as_ptr() as *const T;
-        let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
-        s
-    }
-}
-
-impl SafeSliceAccess for u8 {}
-impl SafeSliceAccess for i8 {}
-impl SafeSliceAccess for bool {}
-
-// TODO(caspern): Get rid of this. Conditional compliation is unnecessary complexity.
-// Vectors of primitives just don't work on big endian machines!!!
-#[cfg(target_endian = "little")]
-mod le_safe_slice_impls {
-    impl super::SafeSliceAccess for u16 {}
-    impl super::SafeSliceAccess for u32 {}
-    impl super::SafeSliceAccess for u64 {}
-
-    impl super::SafeSliceAccess for i16 {}
-    impl super::SafeSliceAccess for i32 {}
-    impl super::SafeSliceAccess for i64 {}
-
-    impl super::SafeSliceAccess for f32 {}
-    impl super::SafeSliceAccess for f64 {}
-}
-
-#[cfg(target_endian = "little")]
-pub use self::le_safe_slice_impls::*;
-
-pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
+/// # Safety
+///
+/// `buf` must contain a value of T at `loc` and have alignment of 1
+pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
+    assert_eq!(align_of::<T>(), 1);
     let sz = size_of::<T>();
     let buf = &buf[loc..loc + sz];
     let ptr = buf.as_ptr() as *const T;
-    unsafe { &*ptr }
+    // SAFETY
+    // buf contains a value at loc of type T and T has no alignment requirements
+    &*ptr
 }
 
 impl<'a> Follow<'a> for &'a str {
     type Inner = &'a str;
-    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
-        let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) } as usize;
+    unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
         let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
-        unsafe { from_utf8_unchecked(slice) }
+        from_utf8_unchecked(slice)
     }
 }
 
-#[cfg(target_endian = "little")]
-fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
-    let sz = size_of::<T>();
-    debug_assert!(sz > 0);
-    let len = unsafe { read_scalar_at::<UOffsetT>(buf, loc) as usize };
-    let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
-    let ptr = data_buf.as_ptr() as *const T;
-    let s: &[T] = unsafe { from_raw_parts(ptr, len) };
-    s
-}
-
-/// Implement direct slice access if the host is little-endian.
-#[cfg(target_endian = "little")]
-impl<'a, T: EndianScalar> Follow<'a> for &'a [T] {
-    type Inner = &'a [T];
-    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
-        follow_slice_helper::<T>(buf, loc)
+impl<'a> Follow<'a> for &'a [u8] {
+    type Inner = &'a [u8];
+    unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+        let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
+        &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
     }
 }
 
 /// Implement Follow for all possible Vectors that have Follow-able elements.
 impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
     type Inner = Vector<'a, T>;
-    fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+    unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
         Vector::new(buf, loc)
     }
 }
@@ -201,8 +169,14 @@
         }
     }
 
+    /// Creates a new `VectorIter` from the provided slice
+    ///
+    /// # Safety
+    ///
+    /// buf must contain a contiguous sequence of `items_num` values of `T`
+    ///
     #[inline]
-    pub fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
+    pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
         VectorIter {
             buf,
             loc: 0,
@@ -235,7 +209,10 @@
         if self.remaining == 0 {
             None
         } else {
-            let result = T::follow(self.buf, self.loc);
+            // Safety:
+            // VectorIter can only be created from a contiguous sequence of `items_num`
+            // And remaining is initialized to `items_num`
+            let result = unsafe { T::follow(self.buf, self.loc) };
             self.loc += sz;
             self.remaining -= 1;
             Some(result)
@@ -272,7 +249,10 @@
             None
         } else {
             self.remaining -= 1;
-            Some(T::follow(self.buf, self.loc + sz * self.remaining))
+            // Safety:
+            // VectorIter can only be created from a contiguous sequence of `items_num`
+            // And remaining is initialized to `items_num`
+            Some(unsafe { T::follow(self.buf, self.loc + sz * self.remaining) })
         }
     }
 
@@ -309,7 +289,7 @@
     }
 }
 
-#[cfg(feature="serialize")]
+#[cfg(feature = "serialize")]
 impl<'a, T> serde::ser::Serialize for Vector<'a, T>
 where
     T: 'a + Follow<'a>,