Change `upb` crate source to not use std or alloc

PiperOrigin-RevId: 671865731
diff --git a/rust/upb.rs b/rust/upb.rs
index 7ace10e..5cd4bb4 100644
--- a/rust/upb.rs
+++ b/rust/upb.rs
@@ -13,7 +13,6 @@
     Proxied, ProxiedInMapValue, ProxiedInRepeated, Repeated, RepeatedMut, RepeatedView, View,
 };
 use core::fmt::Debug;
-use std::alloc::Layout;
 use std::mem::{size_of, ManuallyDrop, MaybeUninit};
 use std::ptr::{self, NonNull};
 use std::slice;
@@ -133,21 +132,6 @@
     }
 }
 
-fn copy_bytes_in_arena<'msg>(arena: &'msg Arena, val: &'msg [u8]) -> &'msg [u8] {
-    // SAFETY: the alignment of `[u8]` is less than `UPB_MALLOC_ALIGN`.
-    let new_alloc = unsafe { arena.alloc(Layout::for_value(val)) };
-    debug_assert_eq!(new_alloc.len(), val.len());
-
-    let start: *mut u8 = new_alloc.as_mut_ptr().cast();
-    // SAFETY:
-    // - `new_alloc` is writeable for `val.len()` bytes.
-    // - After the copy, `new_alloc` is initialized for `val.len()` bytes.
-    unsafe {
-        val.as_ptr().copy_to_nonoverlapping(start, val.len());
-        &*(new_alloc as *mut _ as *mut [u8])
-    }
-}
-
 /// Kernel-specific owned `string` and `bytes` field type.
 #[doc(hidden)]
 pub struct InnerProtoString(OwnedArenaBox<[u8]>);
@@ -167,7 +151,7 @@
 impl From<&[u8]> for InnerProtoString {
     fn from(val: &[u8]) -> InnerProtoString {
         let arena = Arena::new();
-        let in_arena_copy = arena.copy_slice_in(val);
+        let in_arena_copy = arena.copy_slice_in(val).unwrap();
         // SAFETY:
         // - `in_arena_copy` is valid slice that will live for `arena`'s lifetime and
         //   this is the only reference in the program to it.
@@ -354,7 +338,7 @@
                             len
                         );
                         for (src_ptr, dest_ptr) in src_ptrs.iter().zip(dest_ptrs) {
-                            *dest_ptr = copy_bytes_in_arena(&arena, src_ptr.as_ref()).into();
+                            *dest_ptr = arena.copy_slice_in(src_ptr.as_ref()).unwrap().into();
                         }
                     }
                 }
diff --git a/rust/upb/arena.rs b/rust/upb/arena.rs
index d4581ea..5f90c6b 100644
--- a/rust/upb/arena.rs
+++ b/rust/upb/arena.rs
@@ -6,12 +6,11 @@
 // https://developers.google.com/open-source/licenses/bsd
 
 use super::opaque_pointee::opaque_pointee;
-use std::alloc::{self, Layout};
-use std::cell::UnsafeCell;
-use std::marker::PhantomData;
-use std::mem::{align_of, MaybeUninit};
-use std::ptr::{self, NonNull};
-use std::slice;
+use core::cell::UnsafeCell;
+use core::marker::PhantomData;
+use core::mem::{align_of, align_of_val, size_of_val, MaybeUninit};
+use core::ptr::{self, NonNull};
+use core::slice;
 
 opaque_pointee!(upb_Arena);
 pub type RawArena = NonNull<upb_Arena>;
@@ -79,75 +78,85 @@
         self.raw
     }
 
-    /// Allocates some memory on the arena.
+    /// Allocates some memory on the arena. Returns None if the allocation
+    /// failed.
     ///
     /// # Safety
     ///
-    /// - `layout`'s alignment must be less than `UPB_MALLOC_ALIGN`.
+    /// - `align` must be less than `UPB_MALLOC_ALIGN`.
     #[allow(clippy::mut_from_ref)]
     #[inline]
-    pub unsafe fn alloc(&self, layout: Layout) -> &mut [MaybeUninit<u8>] {
-        debug_assert!(layout.align() <= UPB_MALLOC_ALIGN);
+    pub unsafe fn alloc(&self, size: usize, align: usize) -> Option<&mut [MaybeUninit<u8>]> {
+        debug_assert!(align <= UPB_MALLOC_ALIGN);
         // SAFETY: `self.raw` is a valid UPB arena
-        let ptr = unsafe { upb_Arena_Malloc(self.raw, layout.size()) };
-        if ptr.is_null() {
-            alloc::handle_alloc_error(layout);
-        }
+        let ptr = unsafe { upb_Arena_Malloc(self.raw, size) };
 
-        // SAFETY:
-        // - `upb_Arena_Malloc` promises that if the return pointer is non-null, it is
-        //   dereferencable for `size` bytes and has an alignment of `UPB_MALLOC_ALIGN`
-        //   until the arena is destroyed.
-        // - `[MaybeUninit<u8>]` has no alignment requirement, and `ptr` is aligned to a
-        //   `UPB_MALLOC_ALIGN` boundary.
-        unsafe { slice::from_raw_parts_mut(ptr.cast(), layout.size()) }
+        if ptr.is_null() {
+            None
+        } else {
+            // SAFETY:
+            // - `upb_Arena_Malloc` promises that if the return pointer is non-null, it is
+            //   dereferencable for `size` bytes and has an alignment of `UPB_MALLOC_ALIGN`
+            //   until the arena is destroyed.
+            // - `[MaybeUninit<u8>]` has no alignment requirement, and `ptr` is aligned to a
+            //   `UPB_MALLOC_ALIGN` boundary.
+            Some(unsafe { slice::from_raw_parts_mut(ptr.cast(), size) })
+        }
     }
 
-    /// Same as alloc() but panics if `layout.align() > UPB_MALLOC_ALIGN`.
+    /// Same as alloc() but panics if `align > UPB_MALLOC_ALIGN`.
     #[allow(clippy::mut_from_ref)]
     #[inline]
-    pub fn checked_alloc(&self, layout: Layout) -> &mut [MaybeUninit<u8>] {
-        assert!(layout.align() <= UPB_MALLOC_ALIGN);
-        // SAFETY: layout.align() <= UPB_MALLOC_ALIGN asserted.
-        unsafe { self.alloc(layout) }
+    pub fn checked_alloc(&self, size: usize, align: usize) -> Option<&mut [MaybeUninit<u8>]> {
+        assert!(align <= UPB_MALLOC_ALIGN);
+        // SAFETY: align <= UPB_MALLOC_ALIGN asserted.
+        unsafe { self.alloc(size, align) }
     }
 
     /// Copies the T into this arena and returns a pointer to the T data inside
-    /// the arena.
-    pub fn copy_in<'a, T: Copy>(&'a self, data: &T) -> &'a T {
-        let layout = Layout::for_value(data);
-        let alloc = self.checked_alloc(layout);
+    /// the arena. Returns None if the allocation failed.
+    pub fn copy_in<'a, T: Copy>(&'a self, data: &T) -> Option<&'a T> {
+        let size = size_of_val(data);
+        let align = align_of_val(data);
 
-        // SAFETY:
-        // - alloc is valid for `layout.len()` bytes and is the uninit bytes are written
-        //   to not read from until written.
-        // - T is copy so copying the bytes of the value is sound.
-        unsafe {
-            let alloc = alloc.as_mut_ptr().cast::<MaybeUninit<T>>();
-            // let data = (data as *const T).cast::<MaybeUninit<T>>();
-            (*alloc).write(*data)
-        }
+        self.checked_alloc(size, align).map(|alloc| {
+            // SAFETY:
+            // - alloc is valid for `size` bytes and is the uninit bytes are written to not
+            //   read from until written.
+            // - T is copy so copying the bytes of the value is sound.
+            unsafe {
+                let alloc = alloc.as_mut_ptr().cast::<MaybeUninit<T>>();
+                &*(*alloc).write(*data)
+            }
+        })
     }
 
-    pub fn copy_str_in<'a>(&'a self, s: &str) -> &'a str {
-        let copied_bytes = self.copy_slice_in(s.as_bytes());
-        // SAFETY: `copied_bytes` has same contents as `s` and so must meet &str
-        // criteria.
-        unsafe { std::str::from_utf8_unchecked(copied_bytes) }
+    /// Copies the str into this arena and returns a pointer to the T data
+    /// inside the arena. Returns None if the allocation failed.
+    pub fn copy_str_in<'a>(&'a self, s: &str) -> Option<&'a str> {
+        self.copy_slice_in(s.as_bytes()).map(|copied_bytes| {
+            // SAFETY: `copied_bytes` has same contents as `s` and so must meet &str
+            // criteria.
+            unsafe { core::str::from_utf8_unchecked(copied_bytes) }
+        })
     }
 
-    pub fn copy_slice_in<'a, T: Copy>(&'a self, data: &[T]) -> &'a [T] {
-        let layout = Layout::for_value(data);
-        let alloc: *mut T = self.checked_alloc(layout).as_mut_ptr().cast();
-
-        // SAFETY:
-        // - uninit_alloc is valid for `layout.len()` bytes and is the uninit bytes are
-        //   written to not read from until written.
-        // - T is copy so copying the bytes of the values is sound.
-        unsafe {
-            ptr::copy_nonoverlapping(data.as_ptr(), alloc, data.len());
-            slice::from_raw_parts_mut(alloc, data.len())
-        }
+    /// Copies the slice into this arena and returns a pointer to the T data
+    /// inside the arena. Returns None if the allocation failed.
+    pub fn copy_slice_in<'a, T: Copy>(&'a self, data: &[T]) -> Option<&'a [T]> {
+        let size = size_of_val(data);
+        let align = align_of_val(data);
+        self.checked_alloc(size, align).map(|alloc| {
+            let alloc: *mut T = alloc.as_mut_ptr().cast();
+            // SAFETY:
+            // - uninit_alloc is valid for `layout.len()` bytes and is the uninit bytes are
+            //   written to not read from until written.
+            // - T is copy so copying the bytes of the values is sound.
+            unsafe {
+                ptr::copy_nonoverlapping(data.as_ptr(), alloc, data.len());
+                slice::from_raw_parts(alloc, data.len())
+            }
+        })
     }
 
     /// Fuse two arenas so they share the same lifetime.
diff --git a/rust/upb/array.rs b/rust/upb/array.rs
index 1c42cef..6fb7c30 100644
--- a/rust/upb/array.rs
+++ b/rust/upb/array.rs
@@ -7,7 +7,7 @@
 
 use super::opaque_pointee::opaque_pointee;
 use super::{upb_MessageValue, upb_MutableMessageValue, CType, RawArena};
-use std::ptr::NonNull;
+use core::ptr::NonNull;
 
 opaque_pointee!(upb_Array);
 pub type RawArray = NonNull<upb_Array>;
@@ -20,8 +20,8 @@
     pub fn upb_Array_Append(arr: RawArray, val: upb_MessageValue, arena: RawArena) -> bool;
     pub fn upb_Array_Resize(arr: RawArray, size: usize, arena: RawArena) -> bool;
     pub fn upb_Array_Reserve(arr: RawArray, size: usize, arena: RawArena) -> bool;
-    pub fn upb_Array_MutableDataPtr(arr: RawArray) -> *mut std::ffi::c_void;
-    pub fn upb_Array_DataPtr(arr: RawArray) -> *const std::ffi::c_void;
+    pub fn upb_Array_MutableDataPtr(arr: RawArray) -> *mut core::ffi::c_void;
+    pub fn upb_Array_DataPtr(arr: RawArray) -> *const core::ffi::c_void;
     pub fn upb_Array_GetMutable(arr: RawArray, i: usize) -> upb_MutableMessageValue;
 }
 
diff --git a/rust/upb/extension_registry.rs b/rust/upb/extension_registry.rs
index ce7fd26..a61c9eb 100644
--- a/rust/upb/extension_registry.rs
+++ b/rust/upb/extension_registry.rs
@@ -6,7 +6,7 @@
 // https://developers.google.com/open-source/licenses/bsd
 
 use super::opaque_pointee::opaque_pointee;
-use std::ptr::NonNull;
+use core::ptr::NonNull;
 
 opaque_pointee!(upb_ExtensionRegistry);
 pub type RawExtensionRegistry = NonNull<upb_ExtensionRegistry>;
diff --git a/rust/upb/map.rs b/rust/upb/map.rs
index 5b3a8d7..554b43c 100644
--- a/rust/upb/map.rs
+++ b/rust/upb/map.rs
@@ -7,7 +7,7 @@
 
 use super::opaque_pointee::opaque_pointee;
 use super::{upb_MessageValue, CType, RawArena};
-use std::ptr::NonNull;
+use core::ptr::NonNull;
 
 opaque_pointee!(upb_Map);
 pub type RawMap = NonNull<upb_Map>;
diff --git a/rust/upb/message.rs b/rust/upb/message.rs
index 9b5535f..8d39748 100644
--- a/rust/upb/message.rs
+++ b/rust/upb/message.rs
@@ -10,7 +10,7 @@
     upb_ExtensionRegistry, upb_MiniTable, upb_MiniTableField, RawArena, RawArray, RawMap,
     StringView,
 };
-use std::ptr::NonNull;
+use core::ptr::NonNull;
 
 opaque_pointee!(upb_Message);
 pub type RawMessage = NonNull<upb_Message>;
@@ -215,7 +215,7 @@
     pub fn upb_Message_SetBaseField(
         m: RawMessage,
         f: *const upb_MiniTableField,
-        val: *const std::ffi::c_void,
+        val: *const core::ffi::c_void,
     );
 
     /// # Safety
diff --git a/rust/upb/message_value.rs b/rust/upb/message_value.rs
index 5cde4d6..2fdae9d 100644
--- a/rust/upb/message_value.rs
+++ b/rust/upb/message_value.rs
@@ -12,8 +12,8 @@
 #[derive(Clone, Copy)]
 pub union upb_MessageValue {
     pub bool_val: bool,
-    pub float_val: std::ffi::c_float,
-    pub double_val: std::ffi::c_double,
+    pub float_val: core::ffi::c_float,
+    pub double_val: core::ffi::c_double,
     pub uint32_val: u32,
     pub int32_val: i32,
     pub uint64_val: u64,
@@ -24,14 +24,14 @@
     pub msg_val: Option<RawMessage>,
     pub str_val: StringView,
 
-    tagged_msg_val: *const std::ffi::c_void,
+    tagged_msg_val: *const core::ffi::c_void,
 }
 
 impl upb_MessageValue {
     pub fn zeroed() -> Self {
         // SAFETY: zero bytes is a valid representation for at least one value in the
         // union (actually valid for all of them).
-        unsafe { std::mem::zeroed() }
+        unsafe { core::mem::zeroed() }
     }
 }
 
diff --git a/rust/upb/mini_table.rs b/rust/upb/mini_table.rs
index 440a695..6261891 100644
--- a/rust/upb/mini_table.rs
+++ b/rust/upb/mini_table.rs
@@ -6,7 +6,7 @@
 // https://developers.google.com/open-source/licenses/bsd
 
 use super::opaque_pointee::opaque_pointee;
-use std::ptr::NonNull;
+use core::ptr::NonNull;
 
 opaque_pointee!(upb_MiniTable);
 pub type RawMiniTable = NonNull<upb_MiniTable>;
diff --git a/rust/upb/opaque_pointee.rs b/rust/upb/opaque_pointee.rs
index 90033f1..d89d5b1 100644
--- a/rust/upb/opaque_pointee.rs
+++ b/rust/upb/opaque_pointee.rs
@@ -15,7 +15,7 @@
         #[repr(C)]
         pub struct $name {
             _data: [u8; 0],
-            _marker: std::marker::PhantomData<(*mut u8, std::marker::PhantomPinned)>,
+            _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
         }
     };
 }
diff --git a/rust/upb/owned_arena_box.rs b/rust/upb/owned_arena_box.rs
index c4ff1ac..6cfc8e7 100644
--- a/rust/upb/owned_arena_box.rs
+++ b/rust/upb/owned_arena_box.rs
@@ -6,9 +6,9 @@
 // https://developers.google.com/open-source/licenses/bsd
 
 use super::Arena;
-use std::fmt::{self, Debug};
-use std::ops::{Deref, DerefMut};
-use std::ptr::NonNull;
+use core::fmt::{self, Debug};
+use core::ops::{Deref, DerefMut};
+use core::ptr::NonNull;
 
 /// An 'owned' T, similar to a Box<T> where the T is data
 /// held in a upb Arena. By holding the data pointer and a corresponding arena
@@ -18,7 +18,7 @@
 /// inside `arena`. This avoids typical concerns of self-referential data
 /// structures because `arena` modifications (other than drop) will never
 /// invalidate `data`, and `data` and `arena` are both behind indirections which
-/// avoids any concern with std::mem::swap.
+/// avoids any concern with core::mem::swap.
 pub struct OwnedArenaBox<T: ?Sized + 'static> {
     data: NonNull<T>,
     arena: Arena,
@@ -87,7 +87,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use std::str;
+    use core::str;
 
     #[test]
     fn test_byte_slice_pointer_roundtrip() {
@@ -101,7 +101,7 @@
     fn test_alloc_str_roundtrip() {
         let arena = Arena::new();
         let s: &str = "Hello";
-        let arena_alloc_str: NonNull<str> = arena.copy_str_in(s).into();
+        let arena_alloc_str: NonNull<str> = arena.copy_str_in(s).unwrap().into();
         let owned_data = unsafe { OwnedArenaBox::new(arena_alloc_str, arena) };
         assert_eq!(&*owned_data, s);
     }
@@ -109,7 +109,7 @@
     #[test]
     fn test_sized_type_roundtrip() {
         let arena = Arena::new();
-        let arena_alloc_u32: NonNull<u32> = arena.copy_in(&7u32).into();
+        let arena_alloc_u32: NonNull<u32> = arena.copy_in(&7u32).unwrap().into();
         let mut owned_data = unsafe { OwnedArenaBox::new(arena_alloc_u32, arena) };
         assert_eq!(*owned_data, 7);
         *owned_data = 8;
diff --git a/rust/upb/string_view.rs b/rust/upb/string_view.rs
index 55c6042..c39b2b2 100644
--- a/rust/upb/string_view.rs
+++ b/rust/upb/string_view.rs
@@ -7,11 +7,11 @@
 
 /// ABI compatible struct with upb_StringView.
 ///
-/// Note that this has semantics similar to `std::string_view` in C++ and
+/// Note that this has semantics similar to `core::string_view` in C++ and
 /// `&[u8]` in Rust, but is not ABI-compatible with either.
 ///
 /// If `len` is 0, then `ptr` is allowed to be either null or dangling. C++
-/// considers a dangling 0-len `std::string_view` to be invalid, and Rust
+/// considers a dangling 0-len `core::string_view` to be invalid, and Rust
 /// considers a `&[u8]` with a null data pointer to be invalid.
 #[repr(C)]
 #[derive(Copy, Clone)]
@@ -38,7 +38,7 @@
             // SAFETY:
             // - `ptr` is non-null
             // - `ptr` is valid for `len` bytes as promised by the caller.
-            unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
+            unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
         }
     }
 }
diff --git a/rust/upb/text.rs b/rust/upb/text.rs
index 2f1cf09..56dddb8 100644
--- a/rust/upb/text.rs
+++ b/rust/upb/text.rs
@@ -50,7 +50,7 @@
     //   `mt`
     // - `buf` is nullptr and `buf_len` is 0
     let len =
-        unsafe { upb_DebugString(msg, mt, Options::NoSortMaps as i32, std::ptr::null_mut(), 0) };
+        unsafe { upb_DebugString(msg, mt, Options::NoSortMaps as i32, core::ptr::null_mut(), 0) };
     assert!(len < isize::MAX as usize);
     // +1 for the trailing NULL
     let mut buf = vec![0u8; len + 1];
diff --git a/rust/upb/wire.rs b/rust/upb/wire.rs
index 75e666f..eb08e7b 100644
--- a/rust/upb/wire.rs
+++ b/rust/upb/wire.rs
@@ -50,7 +50,7 @@
     mini_table: *const upb_MiniTable,
 ) -> Result<Vec<u8>, EncodeStatus> {
     let arena = Arena::new();
-    let mut buf: *mut u8 = std::ptr::null_mut();
+    let mut buf: *mut u8 = core::ptr::null_mut();
     let mut len = 0usize;
 
     // SAFETY:
@@ -61,7 +61,7 @@
     if status == EncodeStatus::Ok {
         assert!(!buf.is_null()); // EncodeStatus Ok should never return NULL data, even for len=0.
         // SAFETY: upb guarantees that `buf` is valid to read for `len`.
-        Ok(unsafe { &*std::ptr::slice_from_raw_parts(buf, len) }.to_vec())
+        Ok(unsafe { &*core::ptr::slice_from_raw_parts(buf, len) }.to_vec())
     } else {
         Err(status)
     }
@@ -88,7 +88,7 @@
     // - `buf` is legally readable for at least `buf_size` bytes.
     // - `extreg` is null.
     let status =
-        unsafe { upb_Decode(buf, len, msg, mini_table, std::ptr::null(), options, arena.raw()) };
+        unsafe { upb_Decode(buf, len, msg, mini_table, core::ptr::null(), options, arena.raw()) };
     match status {
         DecodeStatus::Ok => Ok(()),
         _ => Err(status),