Inplace analysis fix.
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 14 Nov 2010 07:52:22 +0000 (23:52 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 14 Nov 2010 07:52:22 +0000 (23:52 -0800)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py

index 6069f1d392f3845640c0ca8a0c4558dd5ca9448e..6cf4855cbf97f68c878c7054c8102b906585e7d0 100755 (executable)
@@ -5359,6 +5359,9 @@ class BinopNode(ExprNode):
     def analyse_types(self, env):
         self.operand1.analyse_types(env)
         self.operand2.analyse_types(env)
+        self.analyse_operation(env)
+    
+    def analyse_operation(self, env):
         if self.is_py_operation():
             self.coerce_operands_to_pyobjects(env)
             self.type = self.result_type(self.operand1.type,
@@ -5653,12 +5656,12 @@ class DivNode(NumBinopNode):
         except Exception, e:
             self.compile_time_value_error(e)
 
-    def analyse_types(self, env):
+    def analyse_operation(self, env):
         if self.cdivision or env.directives['cdivision']:
             self.ctruedivision = False
         else:
             self.ctruedivision = self.truedivision
-        NumBinopNode.analyse_types(self, env)
+        NumBinopNode.analyse_operation(self, env)
         if self.is_cpp_operation():
             self.cdivision = True
         if not self.type.is_pyobject:
index 37c62e0ccf18024f2aa45f20705bc7259e4294cd..1530c0c9d05124cec809a9a463cb0ff3ebc52071 100644 (file)
@@ -1184,6 +1184,7 @@ class ExpandInplaceOperators(EnvTransform):
             # There is code to handle this case.
             return node
 
+        env = self.current_env()
         def side_effect_free_reference(node, setting=False):
             if isinstance(node, NameNode):
                 return node, []
@@ -1206,18 +1207,23 @@ class ExpandInplaceOperators(EnvTransform):
             lhs, let_ref_nodes = side_effect_free_reference(lhs, setting=True)
         except ValueError:
             return node
+        lhs.analyse_types(env)
         dup = lhs.__class__(**lhs.__dict__)
         binop = binop_node(node.pos, 
                            operator = node.operator,
                            operand1 = dup,
                            operand2 = rhs,
                            inplace=True)
-        node = SingleAssignmentNode(node.pos, lhs=lhs, rhs=binop)
+        binop.analyse_operation(env)
+        node = SingleAssignmentNode(
+                            node.pos, 
+                            lhs = lhs,
+                            rhs=binop.coerce_to(lhs.type, env))
         # Use LetRefNode to avoid side effects.
         let_ref_nodes.reverse()
         for t in let_ref_nodes:
             node = LetNode(t, node)
-        node.analyse_expressions(self.current_env())
+        # Manually analyse types for new node.
         return node
 
     def visit_ExprNode(self, node):