Commit a819fc64 authored by Stefan Behnel's avatar Stefan Behnel

implement independent coercion of subexpressions for conditional if-else expression

parent b93d3f4b
...@@ -9650,8 +9650,9 @@ class CondExprNode(ExprNode): ...@@ -9650,8 +9650,9 @@ class CondExprNode(ExprNode):
return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env) return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
def infer_type(self, env): def infer_type(self, env):
return PyrexTypes.independent_spanning_type(self.true_val.infer_type(env), return PyrexTypes.independent_spanning_type(
self.false_val.infer_type(env)) self.true_val.infer_type(env),
self.false_val.infer_type(env))
def calculate_constant_result(self): def calculate_constant_result(self):
if self.test.constant_result: if self.test.constant_result:
...@@ -9663,17 +9664,27 @@ class CondExprNode(ExprNode): ...@@ -9663,17 +9664,27 @@ class CondExprNode(ExprNode):
self.test = self.test.analyse_types(env).coerce_to_boolean(env) self.test = self.test.analyse_types(env).coerce_to_boolean(env)
self.true_val = self.true_val.analyse_types(env) self.true_val = self.true_val.analyse_types(env)
self.false_val = self.false_val.analyse_types(env) self.false_val = self.false_val.analyse_types(env)
self.type = PyrexTypes.independent_spanning_type(self.true_val.type, self.false_val.type) self.is_temp = 1
return self.analyse_result_type(env)
def analyse_result_type(self, env):
self.type = PyrexTypes.independent_spanning_type(
self.true_val.type, self.false_val.type)
if self.type.is_pyobject: if self.type.is_pyobject:
self.result_ctype = py_object_type self.result_ctype = py_object_type
if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject: if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
self.true_val = self.true_val.coerce_to(self.type, env) self.true_val = self.true_val.coerce_to(self.type, env)
self.false_val = self.false_val.coerce_to(self.type, env) self.false_val = self.false_val.coerce_to(self.type, env)
self.is_temp = 1
if self.type == PyrexTypes.error_type: if self.type == PyrexTypes.error_type:
self.type_error() self.type_error()
return self return self
def coerce_to(self, dst_type, env):
self.true_val = self.true_val.coerce_to(dst_type, env)
self.false_val = self.false_val.coerce_to(dst_type, env)
self.result_ctype = None
return self.analyse_result_type(env)
def type_error(self): def type_error(self):
if not (self.true_val.type.is_error or self.false_val.type.is_error): if not (self.true_val.type.is_error or self.false_val.type.is_error):
error(self.pos, "Incompatible types in conditional expression (%s; %s)" % error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
......
...@@ -31,3 +31,14 @@ def test_cpp_pyobject_cast(Foo obj1, Foo obj2, cond): ...@@ -31,3 +31,14 @@ def test_cpp_pyobject_cast(Foo obj1, Foo obj2, cond):
(<Foo>, None) (<Foo>, None)
""" """
return func(obj1 if cond else obj2, obj1.data if cond else obj2.data) return func(obj1 if cond else obj2, obj1.data if cond else obj2.data)
def test_charptr_coercion(x):
"""
>>> print(test_charptr_coercion(True))
abc
>>> print(test_charptr_coercion(False))
def
"""
cdef char* s = 'abc' if x else 'def'
return s.decode('ascii')
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