Commit d8b19074 authored by Stefan Behnel's avatar Stefan Behnel

drop C array unpacking back into C instead of going back and forth through Python list coercion

parent 3ae163a6
......@@ -4830,19 +4830,16 @@ class SingleAssignmentNode(AssignmentNode):
def unroll(self, node, target_size, env):
from . import ExprNodes, UtilNodes
base = node
start_node = stop_node = step_node = check_node = None
if node.type.is_ctuple:
if node.type.size == target_size:
base = node
start_node = None
stop_node = None
step_node = None
check_node = None
else:
error(self.pos, "Unpacking type %s requires exactly %s arguments." % (
node.type, node.type.size))
return
slice_size = node.type.size
elif node.type.is_ptr:
elif node.type.is_ptr or node.type.is_array:
while isinstance(node, ExprNodes.SliceIndexNode) and not (node.start or node.stop):
base = node = node.base
if isinstance(node, ExprNodes.SliceIndexNode):
base = node.base
start_node = node.start
......@@ -4875,19 +4872,25 @@ class SingleAssignmentNode(AssignmentNode):
try:
slice_size = (get_const(stop_node, None) - get_const(start_node, 0)) / get_const(step_node, 1)
if target_size != slice_size:
error(self.pos, "Assignment to/from slice of wrong length, expected %d, got %d" % (
slice_size, target_size))
except ValueError:
error(self.pos, "C array assignment currently requires known endpoints")
return
check_node = None
elif node.type.is_array:
slice_size = node.type.size
if not isinstance(slice_size, (int, long)):
return # might still work when coercing to Python
else:
return
else:
return
if slice_size != target_size:
error(self.pos, "Assignment to/from slice of wrong length, expected %s, got %s" % (
slice_size, target_size))
return
items = []
base = UtilNodes.LetRefNode(base)
refs = [base]
......
......@@ -162,7 +162,12 @@ def test_starred_from_array():
return x, y, z
@cython.test_fail_if_path_exists(
'//ParallelAssignmentNode//CoerceToPyTypeNode',
'//ParallelAssignmentNode//CoerceFromPyTypeNode',
)
@cython.test_assert_path_exists(
'//ParallelAssignmentNode',
'//ReturnStatNode//CoerceToPyTypeNode'
)
def test_multiple_from_array():
......@@ -170,7 +175,6 @@ def test_multiple_from_array():
>>> test_multiple_from_array()
(1, 2, 3)
"""
# FIXME: copy currently goes through a Python list, even though we infer the right target types
cdef int[3] a
a[0] = 1
a[1] = 2
......@@ -179,6 +183,26 @@ def test_multiple_from_array():
return x, y, z
@cython.test_fail_if_path_exists(
'//ParallelAssignmentNode//CoerceToPyTypeNode'
)
@cython.test_assert_path_exists(
'//ParallelAssignmentNode',
'//ReturnStatNode//CoerceToPyTypeNode'
)
def test_multiple_from_array_full_slice():
"""
>>> test_multiple_from_array_full_slice()
(1, 2, 3)
"""
cdef int[3] a
a[0] = 1
a[1] = 2
a[2] = 3
x, y, z = a[:]
return x, y, z
@cython.test_fail_if_path_exists(
'//ParallelAssignmentNode//CoerceToPyTypeNode'
)
......
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