@@ -91,7 +91,7 @@ def lift_legacy_condition(
9191 return Binary (Binary .Op .EQUAL , left , right , types .Bool ())
9292
9393
94- def lift (value : typing .Any , / , type : types .Type | None = None ) -> Expr :
94+ def lift (value : typing .Any , / , type : types .Type | None = None , * , try_const : bool = True ) -> Expr :
9595 """Lift the given Python ``value`` to a :class:`~.expr.Value` or :class:`~.expr.Var`.
9696
9797 If an explicit ``type`` is given, the typing in the output will reflect that.
@@ -125,7 +125,7 @@ def lift(value: typing.Any, /, type: types.Type | None = None) -> Expr:
125125
126126 inferred : types .Type
127127 if value is True or value is False :
128- inferred = types .Bool (const = True )
128+ inferred = types .Bool (const = try_const )
129129 constructor = Value
130130 elif isinstance (value , Clbit ):
131131 inferred = types .Bool ()
@@ -136,7 +136,7 @@ def lift(value: typing.Any, /, type: types.Type | None = None) -> Expr:
136136 elif isinstance (value , int ):
137137 if value < 0 :
138138 raise ValueError ("cannot represent a negative value" )
139- inferred = types .Uint (width = value .bit_length () or 1 , const = True )
139+ inferred = types .Uint (width = value .bit_length () or 1 , const = try_const )
140140 constructor = Value
141141 else :
142142 raise TypeError (f"failed to infer a type for '{ value } '" )
@@ -223,24 +223,19 @@ def _lift_binary_operands(left: typing.Any, right: typing.Any) -> tuple[Expr, Ex
223223 right_int = isinstance (right , int ) and not right_bool
224224 if not (left_int or right_int ):
225225 if left_bool == right_bool :
226- # If they're both bool, lifting them will produce const Bool.
227- # If neither are bool, they're a mix of bits/registers (which are always
228- # non-const) and Expr, which we can't modify the const-ness of without
229- # a cast node.
230- left = lift (left )
231- right = lift (right )
226+ # If they're both bool, they'll lift as const here.
227+ # If neither are, we've already checked for int, so they must be bits,
228+ # registers, or expressions, none of which we can't lift to be const.
229+ left = lift (left , try_const = True )
230+ right = lift (right , try_const = True )
232231 elif not right_bool :
233- # Left is a bool
232+ # Left is a bool, which should only be const if right is const.
234233 right = lift (right )
235- # TODO: if right.type isn't Bool, there's a type mismatch so we _should_
236- # raise here. But, _binary_bitwise will error for us with a better msg.
237- left = lift (left , right .type if right .type .kind is types .Bool else None )
234+ left = lift (left , try_const = right .type .const )
238235 elif not left_bool :
239- # Right is a bool.
236+ # Right is a bool, which should only be const if left is const .
240237 left = lift (left )
241- # TODO: if left.type isn't Bool, there's a type mismatch so we _should_
242- # raise here. But, _binary_bitwise will error for us with a better msg.
243- right = lift (right , left .type if left .type .kind is types .Bool else None )
238+ right = lift (right , try_const = left .type .const )
244239 elif not right_int :
245240 # Left is an int.
246241 right = lift (right )
0 commit comments