diff --git a/rust/upb/associated_mini_table.rs b/rust/upb/associated_mini_table.rs index 382d9a63ac..e8db8fec5c 100644 --- a/rust/upb/associated_mini_table.rs +++ b/rust/upb/associated_mini_table.rs @@ -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. /// -/// 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; +/// 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). + unsafe fn mini_table() -> *const upb_MiniTable; } diff --git a/src/google/protobuf/compiler/rust/accessors/repeated_field.cc b/src/google/protobuf/compiler/rust/accessors/repeated_field.cc index a8f6e2b13b..797ac8f566 100644 --- a/src/google/protobuf/compiler/rust/accessors/repeated_field.cc +++ b/src/google/protobuf/compiler/rust/accessors/repeated_field.cc @@ -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( - ::MINI_TABLE, + ::mini_table(), $field_number$ ) }; diff --git a/src/google/protobuf/compiler/rust/generator.cc b/src/google/protobuf/compiler/rust/generator.cc index 0f44c88a8c..af6cf69efa 100644 --- a/src/google/protobuf/compiler/rust/generator.cc +++ b/src/google/protobuf/compiler/rust/generator.cc @@ -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; diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index e92c3481bd..9def99cad6 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -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(), - ::MINI_TABLE) + ::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(), + ::mini_table()) } )rs"); return; @@ -148,7 +147,7 @@ void MessageClearAndParse(Context& ctx, const Descriptor& msg) { $pbr$::wire::decode( data, msg.raw_msg(), - ::MINI_TABLE, + ::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(), - ::MINI_TABLE + ::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, - ::MINI_TABLE, + ::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(), - ::MINI_TABLE, + ::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, ::MINI_TABLE); + $pbr$::repeated_message_copy_from(src, dest, ::mini_table()); } }