Skip to content

Commit aa10084

Browse files
authored
Merge pull request RustPython#3711 from youknowone/pyexact
PyExact as counterpart of PyRefExact
2 parents c6a66be + cce206c commit aa10084

File tree

6 files changed

+138
-27
lines changed

6 files changed

+138
-27
lines changed

vm/src/builtins/str.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
1717
Iterable, PyComparisonOp, Unconstructible,
1818
},
19-
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
19+
AsObject, Context, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
2020
TryFromBorrowedObject, VirtualMachine,
2121
};
2222
use ascii::{AsciiStr, AsciiString};
@@ -1534,6 +1534,12 @@ impl AsRef<str> for PyRefExact<PyStr> {
15341534
}
15351535
}
15361536

1537+
impl AsRef<str> for PyExact<PyStr> {
1538+
fn as_ref(&self) -> &str {
1539+
self.as_str()
1540+
}
1541+
}
1542+
15371543
#[cfg(test)]
15381544
mod tests {
15391545
use super::*;

vm/src/dictdatatype.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::common::{
1010
use crate::{
1111
builtins::{PyInt, PyStr, PyStrRef},
1212
convert::ToPyObject,
13-
AsObject, Py, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine,
13+
AsObject, Py, PyExact, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine,
1414
};
1515
use num_traits::ToPrimitive;
1616
use std::{fmt, mem::size_of, ops::ControlFlow};
@@ -686,39 +686,39 @@ pub trait DictKey {
686686
/// to index dictionaries.
687687
impl DictKey for PyObject {
688688
type Owned = PyObjectRef;
689-
#[inline]
689+
#[inline(always)]
690690
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
691691
self.to_owned()
692692
}
693-
693+
#[inline(always)]
694694
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
695695
self.hash(vm)
696696
}
697-
697+
#[inline(always)]
698698
fn key_is(&self, other: &PyObject) -> bool {
699699
self.is(other)
700700
}
701-
701+
#[inline(always)]
702702
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
703703
vm.identical_or_equal(self, other_key)
704704
}
705-
705+
#[inline]
706706
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
707707
vm.to_index(self)?.try_to_primitive(vm)
708708
}
709709
}
710710

711711
impl DictKey for Py<PyStr> {
712712
type Owned = PyStrRef;
713-
#[inline]
713+
#[inline(always)]
714714
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
715715
self.to_owned()
716716
}
717-
717+
#[inline]
718718
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
719719
Ok(self.hash(vm))
720720
}
721-
721+
#[inline(always)]
722722
fn key_is(&self, other: &PyObject) -> bool {
723723
self.is(other)
724724
}
@@ -732,28 +732,31 @@ impl DictKey for Py<PyStr> {
732732
vm.bool_eq(self.as_object(), other_key)
733733
}
734734
}
735-
735+
#[inline(always)]
736736
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
737737
self.as_object().key_as_isize(vm)
738738
}
739739
}
740740

741-
impl DictKey for PyRefExact<PyStr> {
742-
type Owned = Self;
743-
#[inline]
741+
impl DictKey for PyExact<PyStr> {
742+
type Owned = PyRefExact<PyStr>;
743+
#[inline(always)]
744744
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
745-
self.clone()
745+
self.to_owned()
746746
}
747-
747+
#[inline(always)]
748748
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
749749
(**self).key_hash(vm)
750750
}
751+
#[inline]
751752
fn key_is(&self, other: &PyObject) -> bool {
752753
(**self).key_is(other)
753754
}
755+
#[inline(always)]
754756
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
755757
(**self).key_eq(vm, other_key)
756758
}
759+
#[inline(always)]
757760
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
758761
(**self).key_as_isize(vm)
759762
}
@@ -765,16 +768,16 @@ impl DictKey for PyRefExact<PyStr> {
765768
/// to index dictionaries.
766769
impl DictKey for str {
767770
type Owned = String;
768-
#[inline]
771+
#[inline(always)]
769772
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
770773
self.to_owned()
771774
}
772-
775+
#[inline]
773776
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
774777
// follow a similar route as the hashing of PyStrRef
775778
Ok(vm.state.hash_secret.hash_str(self))
776779
}
777-
780+
#[inline(always)]
778781
fn key_is(&self, _other: &PyObject) -> bool {
779782
// No matter who the other pyobject is, we are never the same thing, since
780783
// we are a str, not a pyobject.

vm/src/intern.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
builtins::{PyStr, PyTypeRef},
33
common::lock::PyRwLock,
44
convert::ToPyObject,
5-
Py, PyObject, PyObjectRef, PyRef, PyRefExact,
5+
Py, PyExact, PyObject, PyObjectRef, PyRef, PyRefExact,
66
};
77
use std::{
88
borrow::{Borrow, ToOwned},
@@ -199,7 +199,7 @@ impl std::fmt::Display for PyStrInterned {
199199
mod sealed {
200200
use crate::{
201201
builtins::PyStr,
202-
object::{Py, PyRefExact},
202+
object::{Py, PyExact, PyRefExact},
203203
};
204204

205205
pub trait SealedInternable {}
@@ -211,7 +211,7 @@ mod sealed {
211211
pub trait SealedMaybeInterned {}
212212

213213
impl SealedMaybeInterned for str {}
214-
impl SealedMaybeInterned for PyRefExact<PyStr> {}
214+
impl SealedMaybeInterned for PyExact<PyStr> {}
215215
impl SealedMaybeInterned for Py<PyStr> {}
216216
}
217217

@@ -259,6 +259,13 @@ impl MaybeInterned for str {
259259
}
260260
}
261261

262+
impl MaybeInterned for PyExact<PyStr> {
263+
#[inline(always)]
264+
fn as_interned(&self) -> Option<&'static PyStrInterned> {
265+
None
266+
}
267+
}
268+
262269
impl MaybeInterned for Py<PyStr> {
263270
#[inline(always)]
264271
fn as_interned(&self) -> Option<&'static PyStrInterned> {

vm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub mod vm;
7777

7878
pub use self::convert::{TryFromBorrowedObject, TryFromObject};
7979
pub use self::object::{
80-
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
80+
AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
8181
};
8282
pub use self::vm::{Context, Interpreter, Settings, VirtualMachine};
8383

vm/src/object/ext.rs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,66 @@ where
5858
}
5959
}
6060

61+
#[repr(transparent)]
62+
pub struct PyExact<T: PyObjectPayload> {
63+
inner: Py<T>,
64+
}
65+
66+
impl<T: PyPayload> PyExact<T> {
67+
/// # Safety
68+
/// Given reference must be exact type of payload T
69+
#[inline(always)]
70+
pub unsafe fn ref_unchecked(r: &Py<T>) -> &Self {
71+
&*(r as *const _ as *const Self)
72+
}
73+
}
74+
75+
impl<T: PyPayload> Deref for PyExact<T> {
76+
type Target = Py<T>;
77+
#[inline(always)]
78+
fn deref(&self) -> &Py<T> {
79+
&self.inner
80+
}
81+
}
82+
83+
impl<T: PyObjectPayload> Borrow<PyObject> for PyExact<T> {
84+
#[inline(always)]
85+
fn borrow(&self) -> &PyObject {
86+
self.inner.borrow()
87+
}
88+
}
89+
90+
impl<T: PyObjectPayload> AsRef<PyObject> for PyExact<T> {
91+
#[inline(always)]
92+
fn as_ref(&self) -> &PyObject {
93+
self.inner.as_ref()
94+
}
95+
}
96+
97+
impl<T: PyObjectPayload> Borrow<Py<T>> for PyExact<T> {
98+
#[inline(always)]
99+
fn borrow(&self) -> &Py<T> {
100+
&self.inner
101+
}
102+
}
103+
104+
impl<T: PyObjectPayload> AsRef<Py<T>> for PyExact<T> {
105+
#[inline(always)]
106+
fn as_ref(&self) -> &Py<T> {
107+
&self.inner
108+
}
109+
}
110+
111+
impl<T: PyPayload> std::borrow::ToOwned for PyExact<T> {
112+
type Owned = PyRefExact<T>;
113+
fn to_owned(&self) -> Self::Owned {
114+
let owned = self.inner.to_owned();
115+
unsafe { PyRefExact::new_unchecked(owned) }
116+
}
117+
}
118+
61119
#[derive(Debug)]
120+
#[repr(transparent)]
62121
pub struct PyRefExact<T: PyObjectPayload> {
63122
inner: PyRef<T>,
64123
}
@@ -109,10 +168,31 @@ impl<T: PyPayload> TryFromObject for PyRefExact<T> {
109168
}
110169

111170
impl<T: PyPayload> Deref for PyRefExact<T> {
112-
type Target = PyRef<T>;
171+
type Target = PyExact<T>;
113172
#[inline(always)]
114-
fn deref(&self) -> &PyRef<T> {
115-
&self.inner
173+
fn deref(&self) -> &PyExact<T> {
174+
unsafe { PyExact::ref_unchecked(self.inner.deref()) }
175+
}
176+
}
177+
178+
impl<T: PyObjectPayload> Borrow<PyObject> for PyRefExact<T> {
179+
#[inline(always)]
180+
fn borrow(&self) -> &PyObject {
181+
self.inner.borrow()
182+
}
183+
}
184+
185+
impl<T: PyObjectPayload> AsRef<PyObject> for PyRefExact<T> {
186+
#[inline(always)]
187+
fn as_ref(&self) -> &PyObject {
188+
self.inner.as_ref()
189+
}
190+
}
191+
192+
impl<T: PyObjectPayload> Borrow<Py<T>> for PyRefExact<T> {
193+
#[inline(always)]
194+
fn borrow(&self) -> &Py<T> {
195+
self.inner.borrow()
116196
}
117197
}
118198

@@ -123,6 +203,20 @@ impl<T: PyObjectPayload> AsRef<Py<T>> for PyRefExact<T> {
123203
}
124204
}
125205

206+
impl<T: PyPayload> Borrow<PyExact<T>> for PyRefExact<T> {
207+
#[inline(always)]
208+
fn borrow(&self) -> &PyExact<T> {
209+
self
210+
}
211+
}
212+
213+
impl<T: PyPayload> AsRef<PyExact<T>> for PyRefExact<T> {
214+
#[inline(always)]
215+
fn as_ref(&self) -> &PyExact<T> {
216+
self
217+
}
218+
}
219+
126220
impl<T: PyPayload> ToPyObject for PyRefExact<T> {
127221
#[inline(always)]
128222
fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {

vm/src/prelude.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub use crate::{
22
object::{
3-
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
3+
AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
4+
PyWeakRef,
45
},
56
vm::{Context, Interpreter, Settings, VirtualMachine},
67
};

0 commit comments

Comments
 (0)