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/endian_scalar.rs b/rust/flatbuffers/src/endian_scalar.rs
index 5f50cf1..48cb83e 100644
--- a/rust/flatbuffers/src/endian_scalar.rs
+++ b/rust/flatbuffers/src/endian_scalar.rs
@@ -17,6 +17,24 @@
 
 use core::mem::size_of;
 
+mod private {
+    /// Types that are trivially transmutable are those where any combination of bits
+    /// represents a valid value of that type
+    ///
+    /// For example integral types are TriviallyTransmutable as all bit patterns are valid,
+    /// however, `bool` is not trivially transmutable as only `0` and `1` are valid
+    pub trait TriviallyTransmutable {}
+
+    impl TriviallyTransmutable for i8 {}
+    impl TriviallyTransmutable for i16 {}
+    impl TriviallyTransmutable for i32 {}
+    impl TriviallyTransmutable for i64 {}
+    impl TriviallyTransmutable for u8 {}
+    impl TriviallyTransmutable for u16 {}
+    impl TriviallyTransmutable for u32 {}
+    impl TriviallyTransmutable for u64 {}
+}
+
 /// Trait for values that must be stored in little-endian byte order, but
 /// might be represented in memory as big-endian. Every type that implements
 /// EndianScalar is a valid FlatBuffers scalar value.
@@ -28,144 +46,118 @@
 /// "too much". For example, num-traits provides i128 support, but that is an
 /// invalid FlatBuffers type.
 pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
-    fn to_little_endian(self) -> Self;
-    fn from_little_endian(self) -> Self;
-}
+    type Scalar: private::TriviallyTransmutable;
 
-/// Macro for implementing a no-op endian conversion. This is used for types
-/// that are one byte wide.
-macro_rules! impl_endian_scalar_noop {
-    ($ty:ident) => {
-        impl EndianScalar for $ty {
-            #[inline]
-            fn to_little_endian(self) -> Self {
-                self
-            }
-            #[inline]
-            fn from_little_endian(self) -> Self {
-                self
-            }
-        }
-    };
+    fn to_little_endian(self) -> Self::Scalar;
+
+    fn from_little_endian(v: Self::Scalar) -> Self;
 }
 
 /// Macro for implementing an endian conversion using the stdlib `to_le` and
 /// `from_le` functions. This is used for integer types. It is not used for
 /// floats, because the `to_le` and `from_le` are not implemented for them in
 /// the stdlib.
-macro_rules! impl_endian_scalar_stdlib_le_conversion {
+macro_rules! impl_endian_scalar {
     ($ty:ident) => {
         impl EndianScalar for $ty {
+            type Scalar = Self;
+
             #[inline]
-            fn to_little_endian(self) -> Self {
+            fn to_little_endian(self) -> Self::Scalar {
                 Self::to_le(self)
             }
             #[inline]
-            fn from_little_endian(self) -> Self {
-                Self::from_le(self)
+            fn from_little_endian(v: Self::Scalar) -> Self {
+                Self::from_le(v)
             }
         }
     };
 }
 
-impl_endian_scalar_noop!(bool);
-impl_endian_scalar_noop!(u8);
-impl_endian_scalar_noop!(i8);
+impl_endian_scalar!(u8);
+impl_endian_scalar!(i8);
+impl_endian_scalar!(u16);
+impl_endian_scalar!(u32);
+impl_endian_scalar!(u64);
+impl_endian_scalar!(i16);
+impl_endian_scalar!(i32);
+impl_endian_scalar!(i64);
 
-impl_endian_scalar_stdlib_le_conversion!(u16);
-impl_endian_scalar_stdlib_le_conversion!(u32);
-impl_endian_scalar_stdlib_le_conversion!(u64);
-impl_endian_scalar_stdlib_le_conversion!(i16);
-impl_endian_scalar_stdlib_le_conversion!(i32);
-impl_endian_scalar_stdlib_le_conversion!(i64);
+impl EndianScalar for bool {
+    type Scalar = u8;
+
+    fn to_little_endian(self) -> Self::Scalar {
+        self as u8
+    }
+
+    fn from_little_endian(v: Self::Scalar) -> Self {
+        v != 0
+    }
+}
 
 impl EndianScalar for f32 {
+    type Scalar = u32;
     /// Convert f32 from host endian-ness to little-endian.
     #[inline]
-    fn to_little_endian(self) -> Self {
-        #[cfg(target_endian = "little")]
-        {
-            self
-        }
-        #[cfg(not(target_endian = "little"))]
-        {
-            byte_swap_f32(self)
-        }
+    fn to_little_endian(self) -> u32 {
+        // Floats and Ints have the same endianness on all supported platforms.
+        // <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
+        self.to_bits().to_le()
     }
     /// Convert f32 from little-endian to host endian-ness.
     #[inline]
-    fn from_little_endian(self) -> Self {
-        #[cfg(target_endian = "little")]
-        {
-            self
-        }
-        #[cfg(not(target_endian = "little"))]
-        {
-            byte_swap_f32(self)
-        }
+    fn from_little_endian(v: u32) -> Self {
+        // Floats and Ints have the same endianness on all supported platforms.
+        // <https://doc.rust-lang.org/std/primitive.f32.html#method.from_bits>
+        f32::from_bits(u32::from_le(v))
     }
 }
 
 impl EndianScalar for f64 {
+    type Scalar = u64;
+
     /// Convert f64 from host endian-ness to little-endian.
     #[inline]
-    fn to_little_endian(self) -> Self {
-        #[cfg(target_endian = "little")]
-        {
-            self
-        }
-        #[cfg(not(target_endian = "little"))]
-        {
-            byte_swap_f64(self)
-        }
+    fn to_little_endian(self) -> u64 {
+        // Floats and Ints have the same endianness on all supported platforms.
+        // <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
+        self.to_bits().to_le()
     }
     /// Convert f64 from little-endian to host endian-ness.
     #[inline]
-    fn from_little_endian(self) -> Self {
-        #[cfg(target_endian = "little")]
-        {
-            self
-        }
-        #[cfg(not(target_endian = "little"))]
-        {
-            byte_swap_f64(self)
-        }
+    fn from_little_endian(v: u64) -> Self {
+        // Floats and Ints have the same endianness on all supported platforms.
+        // <https://doc.rust-lang.org/std/primitive.f64.html#method.from_bits>
+        f64::from_bits(u64::from_le(v))
     }
 }
 
-/// Swaps the bytes of an f32.
-#[allow(dead_code)]
-#[inline]
-pub fn byte_swap_f32(x: f32) -> f32 {
-    f32::from_bits(x.to_bits().swap_bytes())
-}
-
-/// Swaps the bytes of an f64.
-#[allow(dead_code)]
-#[inline]
-pub fn byte_swap_f64(x: f64) -> f64 {
-    f64::from_bits(x.to_bits().swap_bytes())
-}
-
 /// Place an EndianScalar into the provided mutable byte slice. Performs
 /// endian conversion, if necessary.
 /// # Safety
-/// Caller must ensure `s.len() > size_of::<T>()`
-/// and `x` does not overlap with `s`.
+/// Caller must ensure `s.len() >= size_of::<T>()`
 #[inline]
 pub unsafe fn emplace_scalar<T: EndianScalar>(s: &mut [u8], x: T) {
+    let size = size_of::<T::Scalar>();
+    debug_assert!(
+        s.len() >= size,
+        "insufficient capacity for emplace_scalar, needed {} got {}",
+        size,
+        s.len()
+    );
+
     let x_le = x.to_little_endian();
     core::ptr::copy_nonoverlapping(
-        &x_le as *const T as *const u8,
+        &x_le as *const T::Scalar as *const u8,
         s.as_mut_ptr() as *mut u8,
-        size_of::<T>(),
+        size,
     );
 }
 
 /// Read an EndianScalar from the provided byte slice at the specified location.
 /// Performs endian conversion, if necessary.
 /// # Safety
-/// Caller must ensure `s.len() > loc + size_of::<T>()`.
+/// Caller must ensure `s.len() >= loc + size_of::<T>()`.
 #[inline]
 pub unsafe fn read_scalar_at<T: EndianScalar>(s: &[u8], loc: usize) -> T {
     read_scalar(&s[loc..])
@@ -177,8 +169,16 @@
 /// Caller must ensure `s.len() > size_of::<T>()`.
 #[inline]
 pub unsafe fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
-    let mut mem = core::mem::MaybeUninit::<T>::uninit();
+    let size = size_of::<T::Scalar>();
+    debug_assert!(
+        s.len() >= size,
+        "insufficient capacity for emplace_scalar, needed {} got {}",
+        size,
+        s.len()
+    );
+
+    let mut mem = core::mem::MaybeUninit::<T::Scalar>::uninit();
     // Since [u8] has alignment 1, we copy it into T which may have higher alignment.
-    core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size_of::<T>());
-    mem.assume_init().from_little_endian()
+    core::ptr::copy_nonoverlapping(s.as_ptr(), mem.as_mut_ptr() as *mut u8, size);
+    T::from_little_endian(mem.assume_init())
 }