Start testing against Rust edition 2024

This change also makes all the necessary fixes to get us compatible with
edition 2024.

I set things up so that we test edition 2024 with Bazel but keep Cargo on
edition 2021. This seems like a nice way to go since it allows us to get full
test coverage of both editions without us having to increment our minimum
supported Rust version.

PiperOrigin-RevId: 816241556
This commit is contained in:
Adam Cozzette 2025-10-07 09:18:58 -07:00 committed by Copybara-Service
parent f8b4a29c50
commit 3ff832936e
15 changed files with 29 additions and 25 deletions

View file

@ -179,9 +179,13 @@ register_toolchains(
)
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust", dev_dependency = True)
# As of October 2025, our minimum supported Rust version is 1.79. However, we
# use 1.85.0 here so that we can get some test coverage with edition 2024.
# Cargo and our Bazel WORKSPACE build are both still on edition 2021.
rust.toolchain(
edition = "2021",
versions = ["1.79.0"],
edition = "2024",
versions = ["1.85.0"],
)
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate", dev_dependency = True)

View file

@ -262,7 +262,7 @@ def _compile_rust(ctx, attr, src, extra_srcs, deps, runtime):
aliases = {runtime: "protobuf"},
output = lib,
metadata = rmeta,
edition = "2021",
edition = "2024",
is_test = False,
rustc_env = {},
compile_data = depset([]),

View file

@ -103,7 +103,7 @@ pub struct InnerProtoString {
owned_ptr: CppStdString,
}
extern "C" {
unsafe extern "C" {
pub fn proto2_rust_Message_delete(m: RawMessage);
pub fn proto2_rust_Message_clear(m: RawMessage);
pub fn proto2_rust_Message_parse(m: RawMessage, input: PtrAndLen) -> bool;
@ -149,7 +149,7 @@ impl From<&[u8]> for InnerProtoString {
}
}
extern "C" {
unsafe extern "C" {
fn proto2_rust_cpp_new_string(src: PtrAndLen) -> CppStdString;
fn proto2_rust_cpp_delete_string(src: CppStdString);
fn proto2_rust_cpp_string_to_view(src: CppStdString) -> PtrAndLen;
@ -324,7 +324,7 @@ impl From<RustStringRawParts> for String {
}
}
extern "C" {
unsafe extern "C" {
fn proto2_rust_utf8_debug_string(raw: RawMessage) -> RustStringRawParts;
}
@ -335,7 +335,7 @@ pub fn debug_string(raw: RawMessage, f: &mut fmt::Formatter<'_>) -> fmt::Result
write!(f, "{dbg_str}")
}
extern "C" {
unsafe extern "C" {
/// # Safety
/// - `raw1` and `raw2` legally dereferenceable MessageLite* pointers.
#[link_name = "proto2_rust_messagelite_equals"]
@ -662,7 +662,7 @@ macro_rules! impl_repeated_primitives {
$reserve_thunk:ident $(,)?
]),* $(,)?) => {
$(
extern "C" {
unsafe extern "C" {
fn $new_thunk() -> RawRepeatedField;
fn $free_thunk(f: RawRepeatedField);
fn $add_thunk(f: RawRepeatedField, v: <$t as CppTypeConversions>::InsertElemType);
@ -747,7 +747,7 @@ macro_rules! impl_repeated_primitives {
impl_repeated_primitives!(i32, u32, i64, u64, f32, f64, bool, ProtoString, ProtoBytes);
extern "C" {
unsafe extern "C" {
pub fn proto2_rust_RepeatedField_Message_new() -> RawRepeatedField;
pub fn proto2_rust_RepeatedField_Message_free(field: RawRepeatedField);
pub fn proto2_rust_RepeatedField_Message_size(field: RawRepeatedField) -> usize;
@ -1354,7 +1354,7 @@ macro_rules! impl_map_primitives {
$remove_thunk:ident,
]),* $(,)?) => {
$(
extern "C" {
unsafe extern "C" {
pub fn $insert_thunk(
m: RawMap,
key: $cpp_type,
@ -1397,7 +1397,7 @@ impl_map_primitives!(
ProtoString, PtrAndLen;
);
extern "C" {
unsafe extern "C" {
fn proto2_rust_thunk_UntypedMapIterator_increment(iter: &mut UntypedMapIterator);
pub fn proto2_rust_map_new(key_prototype: MapValue, value_prototype: MapValue) -> RawMap;

View file

@ -7,8 +7,8 @@
use std::alloc::{alloc, Layout};
#[no_mangle]
extern "C" fn proto2_rust_alloc(size: usize, align: usize) -> *mut u8 {
#[unsafe(no_mangle)]
unsafe extern "C" fn proto2_rust_alloc(size: usize, align: usize) -> *mut u8 {
if size == 0 {
// A 0-sized layout is legal but the global allocator isn't required to support
// it so return a dangling pointer instead.

View file

@ -78,8 +78,8 @@ use utf8;
// If the Upb and C++ kernels are both linked into the same binary, this symbol
// will be defined twice and cause a link error.
#[no_mangle]
extern "C" fn __Disallow_Upb_And_Cpp_In_Same_Binary() {}
#[unsafe(no_mangle)]
unsafe extern "C" fn __Disallow_Upb_And_Cpp_In_Same_Binary() {}
/// An error that happened during parsing.
#[derive(Debug, Clone)]

View file

@ -27,7 +27,7 @@ macro_rules! proto_assert_eq {
// Helper functions invoking C++ Protobuf APIs directly in C++.
// Defined in `test_utils.cc`.
extern "C" {
unsafe extern "C" {
fn TakeOwnershipAndGetOptionalInt64(msg: *mut c_void) -> i64;
fn DeserializeInteropTestMessage(data: *const u8, len: usize) -> *mut c_void;
fn MutateInteropTestMessage(msg: *mut c_void);

View file

@ -17,7 +17,7 @@ pub const UPB_MALLOC_ALIGN: usize = 8;
const _CHECK_UPB_MALLOC_ALIGN_AT_LEAST_POINTER_ALIGNED: () =
assert!(UPB_MALLOC_ALIGN >= align_of::<*const ()>());
extern "C" {
unsafe extern "C" {
// `Option<NonNull<T: Sized>>` is ABI-compatible with `*mut T`
pub fn upb_Arena_New() -> Option<RawArena>;
pub fn upb_Arena_Free(arena: RawArena);

View file

@ -19,7 +19,7 @@ use sys::opaque_pointee::opaque_pointee;
opaque_pointee!(upb_Array);
pub type RawArray = NonNull<upb_Array>;
extern "C" {
unsafe extern "C" {
pub fn upb_Array_New(a: RawArena, r#type: CType) -> RawArray;
pub fn upb_Array_Size(arr: RawArray) -> usize;
pub fn upb_Array_Set(arr: RawArray, i: usize, val: upb_MessageValue);

View file

@ -30,7 +30,7 @@ pub enum MapInsertStatus {
pub const UPB_MAP_BEGIN: usize = usize::MAX;
extern "C" {
unsafe extern "C" {
pub fn upb_Map_New(arena: RawArena, key_type: CType, value_type: CType) -> RawMap;
pub fn upb_Map_Size(map: RawMap) -> usize;
pub fn upb_Map_Insert(

View file

@ -21,7 +21,7 @@ use sys::opaque_pointee::opaque_pointee;
opaque_pointee!(upb_Message);
pub type RawMessage = NonNull<upb_Message>;
extern "C" {
unsafe extern "C" {
/// # Safety
/// - `mini_table` and `arena` must be valid to deref
pub fn upb_Message_New(mini_table: RawMiniTable, arena: RawArena) -> Option<RawMessage>;

View file

@ -51,7 +51,7 @@ pub type RawMiniTableField = NonNull<upb_MiniTableField>;
// we are not currently using it.
opaque_pointee!(upb_Status);
extern "C" {
unsafe extern "C" {
/// Finds the field with the provided number, will return NULL if no such
/// field is found.
///

View file

@ -12,7 +12,7 @@ mod sys {
use sys::message::message::RawMessage;
use sys::mini_table::mini_table::RawMiniTable;
extern "C" {
unsafe extern "C" {
/// Returns the minimum needed length (excluding NULL) that `buf` has to be
/// to hold the `msg`s debug string.
///

View file

@ -39,7 +39,7 @@ pub enum DecodeStatus {
}
// LINT.ThenChange()
extern "C" {
unsafe extern "C" {
// SAFETY:
// - `mini_table` is the one associated with `msg`
// - `buf` and `buf_size` are legally writable.

View file

@ -320,7 +320,7 @@ void GenerateEnumDefinition(Context& ctx, const EnumDescriptor& desc,
}
unsafe fn repeated_free(_private: $pbi$::Private, f: &mut $pb$::Repeated<Self>) {
$pbr$::free_enum_repeated(f)
unsafe { $pbr$::free_enum_repeated(f) }
}
fn repeated_len(r: $pb$::View<$pb$::Repeated<Self>>) -> usize {

View file

@ -795,7 +795,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg, const upb::DefPool& pool) {
}},
},
R"rs(
extern "C" {
unsafe extern "C" {
$message_externs$
$accessor_externs$
$oneof_externs$