@@ -2522,20 +2522,19 @@ def translate_eq_cmp(self, lreg: Value, rreg: Value, expr_op: str, line: int) ->
25222522
25232523 lopt = optional_value_type (ltype )
25242524 ropt = optional_value_type (rtype )
2525+
2526+ # Can we do a quick comparison of two optional types (special case None values)?
25252527 fast_opt_eq = False
2526- if lopt is not None and ropt is not None :
2527- # Can we do a quick comparison of two optional types?
2528- if is_same_type (lopt , ropt ) and is_str_rprimitive (lopt ):
2528+ if lopt is not None :
2529+ if ropt is not None and is_same_type (lopt , ropt ) and self ._never_equal_to_none (lopt ):
25292530 fast_opt_eq = True
2530- elif lopt is not None :
2531- if is_same_type (lopt , rtype ) and is_str_rprimitive (lopt ):
2531+ if is_same_type (lopt , rtype ) and self ._never_equal_to_none (lopt ):
25322532 fast_opt_eq = True
25332533 elif ropt is not None :
2534- if is_same_type (ropt , ltype ) and is_str_rprimitive (ropt ):
2534+ if is_same_type (ropt , ltype ) and self . _never_equal_to_none (ropt ):
25352535 fast_opt_eq = True
2536-
25372536 if fast_opt_eq :
2538- return self .translate_fast_optional_eq_cmp (lreg , rreg , expr_op , line )
2537+ return self ._translate_fast_optional_eq_cmp (lreg , rreg , expr_op , line )
25392538
25402539 if not (isinstance (ltype , RInstance ) and ltype == rtype ):
25412540 return None
@@ -2563,11 +2562,18 @@ def translate_eq_cmp(self, lreg: Value, rreg: Value, expr_op: str, line: int) ->
25632562
25642563 return self .gen_method_call (lreg , op_methods [expr_op ], [rreg ], ltype , line )
25652564
2566- def translate_fast_optional_eq_cmp (
2565+ def _never_equal_to_none (self , typ : RType ) -> bool :
2566+ """Are the values of type never equal to None?"""
2567+ # TODO: Support RInstance with no custom __eq__/__ne__ and other primitive types.
2568+ return is_str_rprimitive (typ ) or is_bytes_rprimitive (typ )
2569+
2570+ def _translate_fast_optional_eq_cmp (
25672571 self , lreg : Value , rreg : Value , expr_op : str , line : int
25682572 ) -> Value :
25692573 if not isinstance (lreg .type , RUnion ):
25702574 lreg , rreg = rreg , lreg
2575+ value_typ = optional_value_type (lreg .type )
2576+ assert value_typ
25712577 res = Register (bool_rprimitive )
25722578 x = self .add (ComparisonOp (lreg , self .none_object (), ComparisonOp .EQ , line ))
25732579 l_none = BasicBlock ()
@@ -2584,12 +2590,13 @@ def translate_fast_optional_eq_cmp(
25842590 self .goto (out )
25852591 self .activate_block (l_not_none )
25862592 if not isinstance (rreg .type , RUnion ):
2587- z = self .compare_strings (
2588- self .unbox_or_cast (lreg , str_rprimitive , line , can_borrow = True , unchecked = True ),
2593+ z = self .translate_eq_cmp (
2594+ self .unbox_or_cast (lreg , value_typ , line , can_borrow = True , unchecked = True ),
25892595 rreg ,
25902596 expr_op ,
25912597 line ,
25922598 )
2599+ assert z is not None
25932600 self .add (Assign (res , z ))
25942601 else :
25952602 r_none = BasicBlock ()
@@ -2600,12 +2607,13 @@ def translate_fast_optional_eq_cmp(
26002607 self .add (Assign (res , self .false ()))
26012608 self .goto (out )
26022609 self .activate_block (r_not_none )
2603- z = self .compare_strings (
2604- self .unbox_or_cast (lreg , str_rprimitive , line , can_borrow = True , unchecked = True ),
2605- self .unbox_or_cast (rreg , str_rprimitive , line , can_borrow = True , unchecked = True ),
2610+ z = self .translate_eq_cmp (
2611+ self .unbox_or_cast (lreg , value_typ , line , can_borrow = True , unchecked = True ),
2612+ self .unbox_or_cast (rreg , value_typ , line , can_borrow = True , unchecked = True ),
26062613 expr_op ,
26072614 line ,
26082615 )
2616+ assert z is not None
26092617 self .add (Assign (res , z ))
26102618 self .goto (out )
26112619 self .activate_block (out )
0 commit comments