Switch AssociatedMiniTable to a fn from an associated const.

PiperOrigin-RevId: 663324366
pull/17826/head
Protobuf Team Bot 3 months ago committed by Copybara-Service
parent 7155a7e95d
commit 115b1925c6
  1. 19
      rust/upb/associated_mini_table.rs
  2. 2
      src/google/protobuf/compiler/rust/accessors/repeated_field.cc
  3. 9
      src/google/protobuf/compiler/rust/generator.cc
  4. 40
      src/google/protobuf/compiler/rust/message.cc

@ -16,15 +16,20 @@ use super::upb_MiniTable;
/// passed in as a parameter, which is referred to as 'the associated MiniTable
/// for the upb_Message instance' in safety comments.
///
/// This trait is a way to statically associate a MiniTable with Rust types
/// This trait is a way to associate a MiniTable with Rust types
/// which hold upb_Message* to simplify ensuring the upb C invariants
/// are maintained.
///
/// Note that this would prefer to be a `const MINI_TABLE: *const upb_MiniTable`
/// to statically associate a single MiniTable, but as long as the MiniTable is
/// an extern "C" we cannot do that without the unstable `const_refs_to_static`.
/// After that feature is stabilized (or if we move the MiniTable generation to
/// .rs) this will be switched.
pub trait AssociatedMiniTable {
/// SAFETY:
/// - The MiniTable pointer must be from Protobuf code generation and follow the
/// corresponding invariants associated with upb's C API (the pointer should
/// always have the same non-null value, the underlying pointee should never
/// be modified and should have 'static lifetime).
pub unsafe trait AssociatedMiniTable {
const MINI_TABLE: *const upb_MiniTable;
/// - The MiniTable pointer must be from Protobuf code generation and follow
/// the corresponding invariants associated with upb's C API (the pointer
/// should always have the same non-null value, the underlying pointee
/// should never be modified and should have 'static lifetime).
unsafe fn mini_table() -> *const upb_MiniTable;
}

@ -114,7 +114,7 @@ void RepeatedField::InMsgImpl(Context& ctx, const FieldDescriptor& field,
pub fn set_$raw_field_name$(&mut self, src: impl $pb$::IntoProxied<$pb$::Repeated<$RsType$>>) {
let minitable_field = unsafe {
$pbr$::upb_MiniTable_FindFieldByNumber(
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE,
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
$field_number$
)
};

@ -177,15 +177,6 @@ bool RustGenerator::Generate(const FileDescriptor* file,
{"Phantom", "::__std::marker::PhantomData"},
});
// On upb we need to enable this feature to be able to have const pointers to
// upb_MiniTables while using the upb C minitable codegen. This
// feature appears that it'll imminently be considered stabilized
// (https://github.com/rust-lang/rust/issues/128183), and if we emit the
// MiniTables as const directly in .rs rather than using the upb minitable .h
// this could be avoided regardless.
if (ctx.is_upb() && file == &rust_generator_context.primary_file()) {
ctx.Emit("#![feature(const_refs_to_static)]\n");
}
ctx.Emit({{"kernel", KernelRsName(ctx.opts().kernel)}}, R"rs(
extern crate protobuf_$kernel$ as __pb;

@ -80,7 +80,7 @@ void MessageSerialize(Context& ctx, const Descriptor& msg) {
// SAFETY: `MINI_TABLE` is the one associated with `self.raw_msg()`.
let encoded = unsafe {
$pbr$::wire::encode(self.raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE)
<Self as $pbr$::AssociatedMiniTable>::mini_table())
};
//~ TODO: This discards the info we have about the reason
//~ of the failure, we should try to keep it instead.
@ -102,12 +102,11 @@ void MessageMutClear(Context& ctx, const Descriptor& msg) {
return;
case Kernel::kUpb:
ctx.Emit(
{
{"minitable", UpbMinitableName(msg)},
},
R"rs(
unsafe {
$pbr$::upb_Message_Clear(self.raw_msg(), $std$::ptr::addr_of!($minitable$))
$pbr$::upb_Message_Clear(
self.raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::mini_table())
}
)rs");
return;
@ -148,7 +147,7 @@ void MessageClearAndParse(Context& ctx, const Descriptor& msg) {
$pbr$::wire::decode(
data,
msg.raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE,
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
msg.arena())
};
match status {
@ -183,7 +182,7 @@ void MessageDebug(Context& ctx, const Descriptor& msg) {
let string = unsafe {
$pbr$::debug_string(
self.raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE
<Self as $pbr$::AssociatedMiniTable>::mini_table()
)
};
write!(f, "{}", string)
@ -297,7 +296,7 @@ void IntoProxiedForMessage(Context& ctx, const Descriptor& msg) {
unsafe { $pbr$::upb_Message_DeepCopy(
dst.inner.msg,
self.msg,
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE,
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
dst.inner.arena.raw(),
) };
dst
@ -319,16 +318,25 @@ void IntoProxiedForMessage(Context& ctx, const Descriptor& msg) {
void UpbGeneratedMessageTraitImpls(Context& ctx, const Descriptor& msg) {
if (ctx.opts().kernel == Kernel::kUpb) {
ctx.Emit({{"minitable", UpbMinitableName(msg)}}, R"rs(
unsafe impl $pbr$::AssociatedMiniTable for $Msg$ {
const MINI_TABLE: *const $pbr$::upb_MiniTable = unsafe { $std$::ptr::addr_of!($minitable$) };
impl $pbr$::AssociatedMiniTable for $Msg$ {
#[inline(always)]
unsafe fn mini_table() -> *const $pbr$::upb_MiniTable {
$std$::ptr::addr_of!($minitable$)
}
}
unsafe impl $pbr$::AssociatedMiniTable for $Msg$View<'_> {
const MINI_TABLE: *const $pbr$::upb_MiniTable = unsafe { $std$::ptr::addr_of!($minitable$) };
impl $pbr$::AssociatedMiniTable for $Msg$View<'_> {
#[inline(always)]
unsafe fn mini_table() -> *const $pbr$::upb_MiniTable {
$std$::ptr::addr_of!($minitable$)
}
}
unsafe impl $pbr$::AssociatedMiniTable for $Msg$Mut<'_> {
const MINI_TABLE: *const $pbr$::upb_MiniTable = unsafe { $std$::ptr::addr_of!($minitable$) };
impl $pbr$::AssociatedMiniTable for $Msg$Mut<'_> {
#[inline(always)]
unsafe fn mini_table() -> *const $pbr$::upb_MiniTable {
$std$::ptr::addr_of!($minitable$)
}
}
)rs");
}
@ -362,7 +370,7 @@ void MessageMutMergeFrom(Context& ctx, const Descriptor& msg) {
assert!(
$pbr$::upb_Message_MergeFrom(self.raw_msg(),
src.as_view().raw_msg(),
<Self as $pbr$::AssociatedMiniTable>::MINI_TABLE,
<Self as $pbr$::AssociatedMiniTable>::mini_table(),
// Use a nullptr for the ExtensionRegistry.
$std$::ptr::null(),
self.arena().raw())
@ -568,7 +576,7 @@ void MessageProxiedInRepeated(Context& ctx, const Descriptor& msg) {
// SAFETY:
// - Elements of `src` and `dest` have message minitable `MINI_TABLE`.
unsafe {
$pbr$::repeated_message_copy_from(src, dest, <Self as $pbr$::AssociatedMiniTable>::MINI_TABLE);
$pbr$::repeated_message_copy_from(src, dest, <Self as $pbr$::AssociatedMiniTable>::mini_table());
}
}

Loading…
Cancel
Save