diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index ddc6510400..bd5837dce9 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -1253,12 +1253,12 @@ mod array { } impl AsMapping for PyArray { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: Some(Self::ass_subscript), - }) + } } fn length(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 2a65036ab2..9b91061da5 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -756,12 +756,12 @@ impl<'a> BufferResizeGuard<'a> for PyByteArray { } impl AsMapping for PyByteArray { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: Some(Self::ass_subscript), - }) + } } #[inline] diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index 53aa561ef3..5131e9abd5 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -569,12 +569,12 @@ impl BufferInternal for PyRef { } impl AsMapping for PyBytes { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: None, - }) + } } #[inline] diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index b3d7d78023..17d799880f 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -416,12 +416,12 @@ impl PyDict { } impl AsMapping for PyDict { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: Some(Self::ass_subscript), - }) + } } #[inline] diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 97af1233de..5ed4f86201 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -418,12 +418,12 @@ impl PyList { } impl AsMapping for PyList { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: Some(Self::ass_subscript), - }) + } } #[inline] diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index e4e386f39f..9df9c0b7e8 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -151,12 +151,12 @@ impl PyMappingProxy { } impl AsMapping for PyMappingProxy { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: None, subscript: Some(Self::subscript), ass_subscript: None, - }) + } } #[inline] diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 7ebdb4910d..56b87f8466 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -737,12 +737,12 @@ impl BufferInternal for PyRef { } impl AsMapping for PyMemoryView { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: Some(Self::ass_subscript), - }) + } } #[inline] diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 751b0b79dd..96e209e048 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -377,12 +377,12 @@ impl PyRange { } impl AsMapping for PyRange { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: None, - }) + } } #[inline] diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index 3f44c75cec..e733143425 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -306,12 +306,12 @@ impl PyTuple { } impl AsMapping for PyTuple { - fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyResult { - Ok(PyMappingMethods { + fn as_mapping(_zelf: &PyRef, _vm: &VirtualMachine) -> PyMappingMethods { + PyMappingMethods { length: Some(Self::length), subscript: Some(Self::subscript), ass_subscript: None, - }) + } } #[inline] diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs index 174652c456..6b4a1dcfed 100644 --- a/vm/src/protocol/mapping.rs +++ b/vm/src/protocol/mapping.rs @@ -36,7 +36,7 @@ impl PyMapping { let obj_cls = self.0.class(); for cls in obj_cls.iter_mro() { if let Some(f) = cls.slots.as_mapping.load() { - return f(&self.0, vm).unwrap(); + return f(&self.0, vm); } } PyMappingMethods::default() diff --git a/vm/src/pyobjectrc.rs b/vm/src/pyobjectrc.rs index 28b01bd3f2..952f3ecc20 100644 --- a/vm/src/pyobjectrc.rs +++ b/vm/src/pyobjectrc.rs @@ -237,6 +237,13 @@ impl PyObjectRef { PyRef::from_obj_unchecked(self) } + /// # Safety + /// T must be the exact payload type + pub unsafe fn downcast_unchecked_ref(&self) -> &PyRef { + debug_assert!(self.payload_is::()); + &*(self as *const PyObjectRef as *const PyRef) + } + pub(crate) fn class_lock(&self) -> &PyRwLock { &self.rc.inner.typ } diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index 39d4e4ad96..4ce18e15d4 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -128,7 +128,7 @@ impl Default for PyTypeFlags { } pub(crate) type GenericMethod = fn(&PyObjectRef, FuncArgs, &VirtualMachine) -> PyResult; -pub(crate) type AsMappingFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult; +pub(crate) type AsMappingFunc = fn(&PyObjectRef, &VirtualMachine) -> PyMappingMethods; pub(crate) type HashFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult; // CallFunc = GenericMethod pub(crate) type GetattroFunc = fn(PyObjectRef, PyStrRef, &VirtualMachine) -> PyResult; @@ -150,7 +150,7 @@ pub(crate) type DescrSetFunc = pub(crate) type NewFunc = fn(PyTypeRef, FuncArgs, &VirtualMachine) -> PyResult; pub(crate) type DelFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<()>; -fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult { +fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyMappingMethods { macro_rules! then_some_closure { ($cond:expr, $closure:expr) => { if $cond { @@ -160,7 +160,7 @@ fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult(vm) @@ -189,7 +189,7 @@ fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult PyResult { @@ -763,10 +763,8 @@ pub trait AsBuffer: PyValue { pub trait AsMapping: PyValue { #[inline] #[pyslot] - fn slot_as_mapping(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyResult { - let zelf = zelf - .downcast_ref() - .ok_or_else(|| vm.new_type_error("unexpected payload for as_mapping".to_owned()))?; + fn slot_as_mapping(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyMappingMethods { + let zelf = unsafe { zelf.downcast_unchecked_ref::() }; Self::as_mapping(zelf, vm) } @@ -792,7 +790,7 @@ pub trait AsMapping: PyValue { }) } - fn as_mapping(zelf: &PyRef, vm: &VirtualMachine) -> PyResult; + fn as_mapping(zelf: &PyRef, vm: &VirtualMachine) -> PyMappingMethods; fn length(zelf: PyObjectRef, _vm: &VirtualMachine) -> PyResult;