Move typeid into vtable (#6231)

* Move typeid into vtable

* Bump rust-version
This commit is contained in:
Noa authored and GitHub committed 2026-01-07 12:33:29 +09:00
1 parent 42cc59a90c
commit 09bde28281
7 files changed
+11 -24

No files matched your search

+1 -1
View File
@@ -131,7 +131,7 @@ members = [
version = "0.4.0"
authors = ["RustPython Team"]
edition = "2024"
rust-version = "1.89.0"
rust-version = "1.91.0"
repository = "https://github.com/RustPython/RustPython"
license = "MIT"
+1 -4
View File
@@ -635,10 +635,7 @@ pub(crate) fn impl_pyclass(attr: PunctuatedNestedMeta, item: Item) -> Result<Tok
quote! {
// static_assertions::const_assert!(std::mem::size_of::<#base_type>() <= std::mem::size_of::<#ident>());
impl ::rustpython_vm::PyPayload for #ident {
#[inline]
fn payload_type_id() -> ::std::any::TypeId {
<#base_type as ::rustpython_vm::PyPayload>::payload_type_id()
}
const PAYLOAD_TYPE_ID: ::core::any::TypeId = <#base_type as ::rustpython_vm::PyPayload>::PAYLOAD_TYPE_ID;
#[inline]
fn validate_downcastable_from(obj: &::rustpython_vm::PyObject) -> bool {
+1 -4
View File
@@ -592,10 +592,7 @@ pub(crate) fn impl_pystruct_sequence(
// Subtype uses base type's payload_type_id
impl ::rustpython_vm::PyPayload for #pytype_ident {
#[inline]
fn payload_type_id() -> ::std::any::TypeId {
<::rustpython_vm::builtins::PyTuple as ::rustpython_vm::PyPayload>::payload_type_id()
}
const PAYLOAD_TYPE_ID: ::core::any::TypeId = <::rustpython_vm::builtins::PyTuple as ::rustpython_vm::PyPayload>::PAYLOAD_TYPE_ID;
#[inline]
fn validate_downcastable_from(obj: &::rustpython_vm::PyObject) -> bool {
+1 -3
View File
@@ -1935,9 +1935,7 @@ impl PyPayload for PyUtf8Str {
ctx.types.str_type
}
fn payload_type_id() -> core::any::TypeId {
core::any::TypeId::of::<PyStr>()
}
const PAYLOAD_TYPE_ID: core::any::TypeId = core::any::TypeId::of::<PyStr>();
fn validate_downcastable_from(obj: &PyObject) -> bool {
// SAFETY: we know the object is a PyStr in this context
+2 -7
View File
@@ -105,8 +105,6 @@ pub(super) unsafe fn try_trace_obj<T: PyPayload>(x: &PyObject, tracer_fn: &mut T
#[repr(C)]
pub(super) struct PyInner<T> {
pub(super) ref_count: RefCount,
// TODO: move typeid into vtable once TypeId::of is const
pub(super) typeid: TypeId,
pub(super) vtable: &'static PyObjVTable,
pub(super) typ: PyAtomicRef<PyType>, // __class__ member
@@ -449,7 +447,6 @@ impl<T: PyPayload + core::fmt::Debug> PyInner<T> {
let member_count = typ.slots.member_count;
Box::new(Self {
ref_count: RefCount::new(),
typeid: T::payload_type_id(),
vtable: PyObjVTable::of::<T>(),
typ: PyAtomicRef::from(typ),
dict: dict.map(InstanceDict::new),
@@ -639,7 +636,7 @@ impl PyObject {
#[deprecated(note = "use downcastable instead")]
#[inline(always)]
pub fn payload_is<T: PyPayload>(&self) -> bool {
self.0.typeid == T::payload_type_id()
self.0.vtable.typeid == T::PAYLOAD_TYPE_ID
}
/// Force to return payload as T.
@@ -722,7 +719,7 @@ impl PyObject {
#[inline]
pub(crate) fn typeid(&self) -> TypeId {
self.0.typeid
self.0.vtable.typeid
}
/// Check if this object can be downcast to T.
@@ -1276,7 +1273,6 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef, PyTypeRef) {
let type_type_ptr = Box::into_raw(Box::new(partially_init!(
PyInner::<PyType> {
ref_count: RefCount::new(),
typeid: TypeId::of::<PyType>(),
vtable: PyObjVTable::of::<PyType>(),
dict: None,
weak_list: WeakRefList::new(),
@@ -1288,7 +1284,6 @@ pub(crate) fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef, PyTypeRef) {
let object_type_ptr = Box::into_raw(Box::new(partially_init!(
PyInner::<PyType> {
ref_count: RefCount::new(),
typeid: TypeId::of::<PyType>(),
vtable: PyObjVTable::of::<PyType>(),
dict: None,
weak_list: WeakRefList::new(),
+2 -5
View File
@@ -26,15 +26,12 @@ pub(crate) fn cold_downcast_type_error(
}
pub trait PyPayload: MaybeTraverse + PyThreadingConstraint + Sized + 'static {
#[inline]
fn payload_type_id() -> core::any::TypeId {
core::any::TypeId::of::<Self>()
}
const PAYLOAD_TYPE_ID: core::any::TypeId = core::any::TypeId::of::<Self>();
/// # Safety: this function should only be called if `payload_type_id` matches the type of `obj`.
#[inline]
fn downcastable_from(obj: &PyObject) -> bool {
obj.typeid() == Self::payload_type_id() && Self::validate_downcastable_from(obj)
obj.typeid() == Self::PAYLOAD_TYPE_ID && Self::validate_downcastable_from(obj)
}
#[inline]
+3
View File
@@ -1,4 +1,5 @@
use alloc::fmt;
use core::any::TypeId;
use crate::{
PyObject,
@@ -11,6 +12,7 @@ use crate::{
use super::{Traverse, TraverseFn};
pub(in crate::object) struct PyObjVTable {
pub(in crate::object) typeid: TypeId,
pub(in crate::object) drop_dealloc: unsafe fn(*mut PyObject),
pub(in crate::object) debug: unsafe fn(&PyObject, &mut fmt::Formatter<'_>) -> fmt::Result,
pub(in crate::object) trace: Option<unsafe fn(&PyObject, &mut TraverseFn<'_>)>,
@@ -19,6 +21,7 @@ pub(in crate::object) struct PyObjVTable {
impl PyObjVTable {
pub const fn of<T: PyObjectPayload>() -> &'static Self {
&Self {
typeid: T::PAYLOAD_TYPE_ID,
drop_dealloc: drop_dealloc_obj::<T>,
debug: debug_obj::<T>,
trace: const {