@@ -130,18 +130,16 @@ impl<T: Clone> Dict<T> {
130130 }
131131
132132 /// Store a key
133- pub fn insert < K : DictKey + IntoPyObject + Copy > (
134- & self ,
135- vm : & VirtualMachine ,
136- key : K ,
137- value : T ,
138- ) -> PyResult < ( ) > {
133+ pub fn insert < K > ( & self , vm : & VirtualMachine , key : K , value : T ) -> PyResult < ( ) >
134+ where
135+ K : DictKey ,
136+ {
139137 // This does not need to be accurate so we can take the lock mutiple times.
140138 if self . borrow_value ( ) . indices . len ( ) > 2 * self . borrow_value ( ) . size {
141139 self . resize ( ) ;
142140 }
143141 loop {
144- match self . lookup ( vm, key) ? {
142+ match self . lookup ( vm, & key) ? {
145143 LookupResult :: Existing ( index) => {
146144 let mut inner = self . borrow_value_mut ( ) ;
147145 // Update existing key
@@ -166,7 +164,7 @@ impl<T: Clone> Dict<T> {
166164 }
167165 }
168166
169- pub fn contains < K : DictKey + Copy > ( & self , vm : & VirtualMachine , key : K ) -> PyResult < bool > {
167+ pub fn contains < K : DictKey > ( & self , vm : & VirtualMachine , key : & K ) -> PyResult < bool > {
170168 if let LookupResult :: Existing ( _) = self . lookup ( vm, key) ? {
171169 Ok ( true )
172170 } else {
@@ -176,7 +174,7 @@ impl<T: Clone> Dict<T> {
176174
177175 /// Retrieve a key
178176 #[ cfg_attr( feature = "flame-it" , flame( "Dict" ) ) ]
179- pub fn get < K : DictKey + Copy > ( & self , vm : & VirtualMachine , key : K ) -> PyResult < Option < T > > {
177+ pub fn get < K : DictKey > ( & self , vm : & VirtualMachine , key : & K ) -> PyResult < Option < T > > {
180178 loop {
181179 if let LookupResult :: Existing ( index) = self . lookup ( vm, key) ? {
182180 if let Some ( entry) = & self . borrow_value ( ) . entries [ index] {
@@ -304,7 +302,7 @@ impl<T: Clone> Dict<T> {
304302
305303 /// Lookup the index for the given key.
306304 #[ cfg_attr( feature = "flame-it" , flame( "Dict" ) ) ]
307- fn lookup < K : DictKey + Copy > ( & self , vm : & VirtualMachine , key : K ) -> PyResult < LookupResult > {
305+ fn lookup < K : DictKey > ( & self , vm : & VirtualMachine , key : & K ) -> PyResult < LookupResult > {
308306 let hash_value = key. do_hash ( vm) ?;
309307 let perturb = hash_value;
310308 let mut hash_index: HashIndex = hash_value;
@@ -359,7 +357,7 @@ impl<T: Clone> Dict<T> {
359357 }
360358
361359 /// Retrieve and delete a key
362- pub fn pop < K : DictKey + Copy > ( & self , vm : & VirtualMachine , key : K ) -> PyResult < Option < T > > {
360+ pub fn pop < K : DictKey > ( & self , vm : & VirtualMachine , key : & K ) -> PyResult < Option < T > > {
363361 loop {
364362 if let LookupResult :: Existing ( index) = self . lookup ( vm, key) ? {
365363 let mut inner = self . borrow_value_mut ( ) ;
@@ -413,41 +411,41 @@ enum LookupResult {
413411/// the dictionary. Typical usecases are:
414412/// - PyObjectRef -> arbitrary python type used as key
415413/// - str -> string reference used as key, this is often used internally
416- pub trait DictKey {
417- fn do_hash ( self , vm : & VirtualMachine ) -> PyResult < HashValue > ;
418- fn do_is ( self , other : & PyObjectRef ) -> bool ;
419- fn do_eq ( self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > ;
414+ pub trait DictKey : IntoPyObject {
415+ fn do_hash ( & self , vm : & VirtualMachine ) -> PyResult < HashValue > ;
416+ fn do_is ( & self , other : & PyObjectRef ) -> bool ;
417+ fn do_eq ( & self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > ;
420418}
421419
422420/// Implement trait for PyObjectRef such that we can use python objects
423421/// to index dictionaries.
424- impl DictKey for & PyObjectRef {
425- fn do_hash ( self , vm : & VirtualMachine ) -> PyResult < HashValue > {
422+ impl DictKey for PyObjectRef {
423+ fn do_hash ( & self , vm : & VirtualMachine ) -> PyResult < HashValue > {
426424 let raw_hash = vm. _hash ( self ) ?;
427425 let mut hasher = DefaultHasher :: new ( ) ;
428426 raw_hash. hash ( & mut hasher) ;
429427 Ok ( hasher. finish ( ) as HashValue )
430428 }
431429
432- fn do_is ( self , other : & PyObjectRef ) -> bool {
430+ fn do_is ( & self , other : & PyObjectRef ) -> bool {
433431 self . is ( other)
434432 }
435433
436- fn do_eq ( self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
434+ fn do_eq ( & self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
437435 vm. identical_or_equal ( self , other_key)
438436 }
439437}
440438
441- impl DictKey for & PyStringRef {
442- fn do_hash ( self , _vm : & VirtualMachine ) -> PyResult < HashValue > {
439+ impl DictKey for PyStringRef {
440+ fn do_hash ( & self , _vm : & VirtualMachine ) -> PyResult < HashValue > {
443441 Ok ( self . hash ( ) )
444442 }
445443
446- fn do_is ( self , other : & PyObjectRef ) -> bool {
444+ fn do_is ( & self , other : & PyObjectRef ) -> bool {
447445 self . is ( other)
448446 }
449447
450- fn do_eq ( self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
448+ fn do_eq ( & self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
451449 if self . is ( other_key) {
452450 Ok ( true )
453451 } else if let Some ( py_str_value) = other_key. payload :: < PyString > ( ) {
@@ -458,49 +456,37 @@ impl DictKey for &PyStringRef {
458456 }
459457}
460458
459+ // AsRef<str> fit this case but not possible in rust 1.46
460+
461461/// Implement trait for the str type, so that we can use strings
462462/// to index dictionaries.
463463impl DictKey for & str {
464- fn do_hash ( self , _vm : & VirtualMachine ) -> PyResult < HashValue > {
464+ fn do_hash ( & self , _vm : & VirtualMachine ) -> PyResult < HashValue > {
465465 // follow a similar route as the hashing of PyStringRef
466- let raw_hash = hash:: hash_value ( & self . to_owned ( ) ) . to_bigint ( ) . unwrap ( ) ;
466+ let raw_hash = hash:: hash_value ( * self ) . to_bigint ( ) . unwrap ( ) ;
467467 let raw_hash = hash:: hash_bigint ( & raw_hash) ;
468468 let mut hasher = DefaultHasher :: new ( ) ;
469469 raw_hash. hash ( & mut hasher) ;
470470 Ok ( hasher. finish ( ) as HashValue )
471471 }
472472
473- fn do_is ( self , _other : & PyObjectRef ) -> bool {
473+ fn do_is ( & self , _other : & PyObjectRef ) -> bool {
474474 // No matter who the other pyobject is, we are never the same thing, since
475475 // we are a str, not a pyobject.
476476 false
477477 }
478478
479- fn do_eq ( self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
479+ fn do_eq ( & self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
480480 if let Some ( py_str_value) = other_key. payload :: < PyString > ( ) {
481- Ok ( py_str_value. as_str ( ) == self )
481+ Ok ( py_str_value. as_str ( ) == * self )
482482 } else {
483483 // Fall back to PyString implementation.
484- let s = vm. new_str ( self . to_owned ( ) ) ;
484+ let s = vm. ctx . new_str ( * self ) ;
485485 s. do_eq ( vm, other_key)
486486 }
487487 }
488488}
489489
490- impl DictKey for & String {
491- fn do_hash ( self , vm : & VirtualMachine ) -> PyResult < HashValue > {
492- self . as_str ( ) . do_hash ( vm)
493- }
494-
495- fn do_is ( self , other : & PyObjectRef ) -> bool {
496- self . as_str ( ) . do_is ( other)
497- }
498-
499- fn do_eq ( self , vm : & VirtualMachine , other_key : & PyObjectRef ) -> PyResult < bool > {
500- self . as_str ( ) . do_eq ( vm, other_key)
501- }
502- }
503-
504490#[ cfg( test) ]
505491mod tests {
506492 use super :: { Dict , DictKey , VirtualMachine } ;
@@ -513,27 +499,27 @@ mod tests {
513499
514500 let key1 = vm. new_bool ( true ) ;
515501 let value1 = vm. new_str ( "abc" . to_owned ( ) ) ;
516- dict. insert ( & vm, & key1, value1. clone ( ) ) . unwrap ( ) ;
502+ dict. insert ( & vm, key1. clone ( ) , value1. clone ( ) ) . unwrap ( ) ;
517503 assert_eq ! ( 1 , dict. len( ) ) ;
518504
519505 let key2 = vm. new_str ( "x" . to_owned ( ) ) ;
520506 let value2 = vm. new_str ( "def" . to_owned ( ) ) ;
521- dict. insert ( & vm, & key2, value2. clone ( ) ) . unwrap ( ) ;
507+ dict. insert ( & vm, key2. clone ( ) , value2. clone ( ) ) . unwrap ( ) ;
522508 assert_eq ! ( 2 , dict. len( ) ) ;
523509
524- dict. insert ( & vm, & key1, value2. clone ( ) ) . unwrap ( ) ;
510+ dict. insert ( & vm, key1. clone ( ) , value2. clone ( ) ) . unwrap ( ) ;
525511 assert_eq ! ( 2 , dict. len( ) ) ;
526512
527513 dict. delete ( & vm, & key1) . unwrap ( ) ;
528514 assert_eq ! ( 1 , dict. len( ) ) ;
529515
530- dict. insert ( & vm, & key1, value2. clone ( ) ) . unwrap ( ) ;
516+ dict. insert ( & vm, key1. clone ( ) , value2. clone ( ) ) . unwrap ( ) ;
531517 assert_eq ! ( 2 , dict. len( ) ) ;
532518
533519 assert_eq ! ( true , dict. contains( & vm, & key1) . unwrap( ) ) ;
534- assert_eq ! ( true , dict. contains( & vm, "x" ) . unwrap( ) ) ;
520+ assert_eq ! ( true , dict. contains( & vm, & "x" ) . unwrap( ) ) ;
535521
536- let val = dict. get ( & vm, "x" ) . unwrap ( ) . unwrap ( ) ;
522+ let val = dict. get ( & vm, & "x" ) . unwrap ( ) . unwrap ( ) ;
537523 vm. bool_eq ( val, value2)
538524 . expect ( "retrieved value must be equal to inserted value." ) ;
539525 }
0 commit comments