@@ -13,15 +13,19 @@ use num_traits::ToPrimitive;
1313fn method_is_overloaded (
1414 class_a : & Py < PyType > ,
1515 class_b : & Py < PyType > ,
16- rop_name : & ' static PyStrInterned ,
16+ rop_name : Option < & ' static PyStrInterned > ,
1717 vm : & VirtualMachine ,
18- ) -> bool {
18+ ) -> PyResult < bool > {
19+ let Some ( rop_name) = rop_name else {
20+ return Ok ( false ) ;
21+ } ;
1922 let Some ( method_b) = class_b. get_attr ( rop_name) else {
20- return false ;
23+ return Ok ( false ) ;
2124 } ;
22- class_a
23- . get_attr ( rop_name)
24- . is_none_or ( |method_a| !vm. identical_or_equal ( & method_a, & method_b) . unwrap_or ( false ) )
25+ class_a. get_attr ( rop_name) . map_or ( Ok ( true ) , |method_a| {
26+ vm. identical_or_equal ( & method_a, & method_b)
27+ . map ( |eq| !eq)
28+ } )
2529}
2630
2731macro_rules! binary_func {
@@ -177,29 +181,29 @@ impl VirtualMachine {
177181
178182 // Number slots are inherited, direct access is O(1)
179183 let slot_a = class_a. slots . as_number . left_binary_op ( op_slot) ;
184+ let slot_a_addr = slot_a. map ( |x| x as usize ) ;
180185 let mut slot_b = None ;
186+ let left_b_addr;
181187
182188 if !class_a. is ( class_b) {
183189 let slot_bb = class_b. slots . as_number . right_binary_op ( op_slot) ;
184- if slot_a. map ( |x| x as usize )
185- != class_b
186- . slots
187- . as_number
188- . left_binary_op ( op_slot)
189- . map ( |x| x as usize )
190- {
191- slot_b = slot_bb;
192- } else if class_b. fast_issubclass ( class_a)
193- && let Some ( rop_name) = op_slot. right_method_name ( self )
194- && method_is_overloaded ( class_a, class_b, rop_name, self )
195- {
190+ if slot_bb. map ( |x| x as usize ) != slot_a_addr {
196191 slot_b = slot_bb;
197192 }
193+ left_b_addr = class_b
194+ . slots
195+ . as_number
196+ . left_binary_op ( op_slot)
197+ . map ( |x| x as usize ) ;
198+ } else {
199+ left_b_addr = slot_a_addr;
198200 }
199201
200202 if let Some ( slot_a) = slot_a {
201203 if let Some ( slot_bb) = slot_b
202204 && class_b. fast_issubclass ( class_a)
205+ && ( slot_a_addr != left_b_addr
206+ || method_is_overloaded ( class_a, class_b, op_slot. right_method_name ( self ) , self ) ?)
203207 {
204208 let ret = slot_bb ( a, b, self ) ?;
205209 if !ret. is ( & self . ctx . not_implemented ) {
@@ -295,29 +299,29 @@ impl VirtualMachine {
295299
296300 // Number slots are inherited, direct access is O(1)
297301 let slot_a = class_a. slots . as_number . left_ternary_op ( op_slot) ;
302+ let slot_a_addr = slot_a. map ( |x| x as usize ) ;
298303 let mut slot_b = None ;
304+ let left_b_addr;
299305
300306 if !class_a. is ( class_b) {
301307 let slot_bb = class_b. slots . as_number . right_ternary_op ( op_slot) ;
302- if slot_a. map ( |x| x as usize )
303- != class_b
304- . slots
305- . as_number
306- . left_ternary_op ( op_slot)
307- . map ( |x| x as usize )
308- {
309- slot_b = slot_bb;
310- } else if class_b. fast_issubclass ( class_a)
311- && let Some ( rop_name) = op_slot. right_method_name ( self )
312- && method_is_overloaded ( class_a, class_b, rop_name, self )
313- {
308+ if slot_bb. map ( |x| x as usize ) != slot_a_addr {
314309 slot_b = slot_bb;
315310 }
311+ left_b_addr = class_b
312+ . slots
313+ . as_number
314+ . left_ternary_op ( op_slot)
315+ . map ( |x| x as usize ) ;
316+ } else {
317+ left_b_addr = slot_a_addr;
316318 }
317319
318320 if let Some ( slot_a) = slot_a {
319321 if let Some ( slot_bb) = slot_b
320322 && class_b. fast_issubclass ( class_a)
323+ && ( slot_a_addr != left_b_addr
324+ || method_is_overloaded ( class_a, class_b, op_slot. right_method_name ( self ) , self ) ?)
321325 {
322326 let ret = slot_bb ( a, b, c, self ) ?;
323327 if !ret. is ( & self . ctx . not_implemented ) {
0 commit comments