Commit 657a0066 authored by Stefan Behnel's avatar Stefan Behnel

make item types of tuple/array unpacking inferable and institutionalise the...

make item types of tuple/array unpacking inferable and institutionalise the IndexNode creation for the inference
parent 0cccf2ab
......@@ -476,6 +476,14 @@ class ExprNode(Node):
# can't be modified as part of globals or closures.
return self.is_literal or self.is_temp or self.type.is_array or self.type.is_cfunction
def inferable_item_node(self, index=0):
"""
Return a node that represents the (type) result of an indexing operation,
e.g. for tuple unpacking or iteration.
"""
return IndexNode(self.pos, base=self, index=IntNode(
self.pos, value=str(index), constant_result=index, type=PyrexTypes.c_py_ssize_t_type))
# --------------- Type Analysis ------------------
def analyse_as_module(self, env):
......@@ -3846,6 +3854,10 @@ class SliceIndexNode(ExprNode):
return PyrexTypes.c_array_type(base_type.base_type, None)
return py_object_type
def inferable_item_node(self, index=0):
# slicing shouldn't change the result type of the base
return self.base.inferable_item_node(index)
def may_be_none(self):
base_type = self.base.type
if base_type:
......
......@@ -776,9 +776,9 @@ class ControlFlowAnalysis(CythonTransform):
if entry is None: # TODO: This shouldn't happen...
return
self.flow.mark_assignment(lhs, rhs, entry)
elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args:
self.mark_assignment(arg)
elif lhs.is_sequence_constructor:
for i, arg in enumerate(lhs.args):
self.mark_assignment(arg, rhs.inferable_item_node(i) if rhs else None)
else:
self._visit(lhs)
......
......@@ -61,8 +61,8 @@ class MarkParallelAssignments(EnvTransform):
parallel_node.assigned_nodes.append(lhs)
elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args:
self.mark_assignment(arg, object_expr)
for i, arg in enumerate(lhs.args):
self.mark_assignment(arg, rhs.inferable_item_node(i))
else:
# Could use this info to infer cdef class attributes...
pass
......
# mode: run
cimport cython
def test_literal_list():
"""
>>> test_literal_list()
......@@ -141,6 +143,8 @@ def test_ptr_literal_list_slice_end():
a[:5] = [1,2,3,4,5]
return (a[0], a[1], a[2], a[3], a[4])
@cython.test_assert_path_exists('//ReturnStatNode//CoerceToPyTypeNode')
def test_multiple_from_slice():
"""
>>> test_multiple_from_slice()
......@@ -150,6 +154,7 @@ def test_multiple_from_slice():
x, y, z = a[1:4]
return x, y, z
def test_slice_from_multiple():
"""
>>> test_slice_from_multiple()
......
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