summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-04-18 13:05:28 +0100
committerda-woods <dw-git@d-woods.co.uk>2020-04-18 13:05:28 +0100
commit35ef5e01f9612acde39c2910914f5666d3b2d89e (patch)
treeea0d7bfa015b335c0527c539a6a0a88e95e5f037
parent879774e59897b2062d5eb0ac1ca92d5e3a3e73ee (diff)
downloadcython-35ef5e01f9612acde39c2910914f5666d3b2d89e.tar.gz
Fix and test "type in fused_type" special-case
-rw-r--r--Cython/Compiler/ParseTreeTransforms.py5
-rw-r--r--tests/run/fused_types.pyx31
2 files changed, 36 insertions, 0 deletions
diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py
index e61c3c09c..abd24b0d5 100644
--- a/Cython/Compiler/ParseTreeTransforms.py
+++ b/Cython/Compiler/ParseTreeTransforms.py
@@ -3279,7 +3279,12 @@ class ReplaceFusedTypeChecks(VisitorTransform):
def visit_PrimaryCmpNode(self, node):
with Errors.local_errors(ignore=True):
type1 = node.operand1.analyse_as_type(self.local_scope)
+ # type2 should not be specialized here as a special case
+ # we always want to check against the global fused type
+ fused_to_specific = self.local_scope.fused_to_specific
+ self.local_scope.fused_to_specific = None
type2 = node.operand2.analyse_as_type(self.local_scope)
+ self.local_scope.fused_to_specific = fused_to_specific
if type1 and type2:
false_node = ExprNodes.BoolNode(node.pos, value=False)
diff --git a/tests/run/fused_types.pyx b/tests/run/fused_types.pyx
index 5d30cd440..649c4f074 100644
--- a/tests/run/fused_types.pyx
+++ b/tests/run/fused_types.pyx
@@ -21,6 +21,7 @@ ctypedef double *p_double
ctypedef int *p_int
fused_type3 = cython.fused_type(int, double)
fused_composite = cython.fused_type(fused_type2, fused_type3)
+just_float = cython.fused_type(float)
def test_pure():
"""
@@ -453,3 +454,33 @@ def test_cdef_func_with_const_fused_arg():
cdef int arg1 = 1
cdef float arg2 = 2.0
cdef_func_const_fused_arg(arg0, &arg1, &arg2)
+
+
+cdef in_check_1(just_float x):
+ return just_float in floating
+
+cdef in_check_2(just_float x, floating y):
+ # the "floating" on the right-hand side of the in statement should not be specialized
+ # - the test should still work.
+ return just_float in floating
+
+cdef in_check_3(floating x):
+ # the floating on the left-hand side of the in statement should be specialized
+ # but the one of the right-hand side should not (so that the test can still work).
+ return floating in floating
+
+def test_fused_in_check():
+ """
+ It should be possible to use fused types on in "x in ...fused_type" statements
+ even if that type is specialized in the function.
+
+ >>> test_fused_in_check()
+ True
+ True
+ True
+ True
+ """
+ print(in_check_1(1.0))
+ print(in_check_2(1.0, 2.0))
+ print(in_check_2[float, double](1.0, 2.0))
+ print(in_check_3[float](1.0))