Commit 706eb1c3 authored by Stefan Behnel's avatar Stefan Behnel

move type coercion in BoolBinopNode chains from analyse_types() completely to...

move type coercion in BoolBinopNode chains from analyse_types() completely to coerce_to() as we may not know the final type that might support all operand types (usually boolean, but potentially user provided types)
parent 9cefcb88
...@@ -9660,28 +9660,32 @@ class BoolBinopNode(ExprNode): ...@@ -9660,28 +9660,32 @@ class BoolBinopNode(ExprNode):
return BoolBinopNode.from_node( return BoolBinopNode.from_node(
self, self,
operator=self.operator, operator=self.operator,
operand1=self.operand1.coerce_to_boolean(env), operand1=self.operand1.coerce_to_boolean(env).coerce_to_simple(env),
operand2=self.operand2.coerce_to_boolean(env), operand2=self.operand2.coerce_to_boolean(env).coerce_to_simple(env),
type=PyrexTypes.c_bint_type, type=PyrexTypes.c_bint_type,
is_temp=self.is_temp) is_temp=self.is_temp)
def coerce_to(self, dst_type, env):
node = BoolBinopNode.from_node(
self,
operator=self.operator,
operand1=self.operand1.coerce_to(dst_type, env).coerce_to_simple(env),
operand2=self.operand2.coerce_to(dst_type, env).coerce_to_simple(env),
type=dst_type,
is_temp=self.is_temp)
if not dst_type.is_pyobject:
if node.operand1.is_ephemeral() or node.operand2.is_ephemeral():
error(self.pos, "Unsafe C derivative of temporary Python reference used in and/or expression")
return node
def analyse_types(self, env): def analyse_types(self, env):
# Note: we do not do any coercion here as we most likely not know the final type anyway.
# We even accept to set self.type to ErrorType.
# Both coercion to the final type and to a "simple" value is left to coerce_to().
self.operand1 = self.operand1.analyse_types(env) self.operand1 = self.operand1.analyse_types(env)
self.operand2 = self.operand2.analyse_types(env) self.operand2 = self.operand2.analyse_types(env)
self.type = PyrexTypes.independent_spanning_type( self.type = PyrexTypes.independent_spanning_type(
self.operand1.type, self.operand2.type) self.operand1.type, self.operand2.type)
# note: self.type might be ErrorType, but we allow this here
# in order to support eventual coercion to boolean
if not self.type.is_pyobject and not self.type.is_error:
if self.operand1.is_ephemeral() or self.operand2.is_ephemeral():
error(self.pos, "Unsafe C derivative of temporary Python reference used in and/or expression")
self.operand1 = self.operand1.coerce_to(self.type, env)
self.operand2 = self.operand2.coerce_to(self.type, env)
# For what we're about to do, it's vital that
# both operands be temp nodes.
self.operand1 = self.operand1.coerce_to_simple(env)
self.operand2 = self.operand2.coerce_to_simple(env)
self.is_temp = 1 self.is_temp = 1
return self return self
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment