fix declaration analysis (and type inference) for comprehensions
authorStefan Behnel <scoder@users.berlios.de>
Sun, 6 Dec 2009 13:29:05 +0000 (14:29 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 6 Dec 2009 13:29:05 +0000 (14:29 +0100)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/TypeInference.py

index bcc993d5564913f1bb525559e5d4ac0811d93906..ae90a98e5ac8801d78ffce5aef381b71324fa4eb 100644 (file)
@@ -3630,15 +3630,14 @@ class ComprehensionNode(ExprNode):
 
     def infer_type(self, env):
         return self.target.infer_type(env)
-    
+
+    def analyse_declarations(self, env):
+        self.append.target = self # this is used in the PyList_Append of the inner loop
+        self.loop.analyse_declarations(env)
+
     def analyse_types(self, env):
         self.target.analyse_expressions(env)
         self.type = self.target.type
-        self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop
-        # We are analysing declarations to late.
-        self.loop.target.analyse_target_declaration(env)
-        env.infer_types()
-        self.loop.analyse_declarations(env)
         self.loop.analyse_expressions(env)
 
     def calculate_result_code(self):
index 8abbd76b80a64534391323c5ee0472756ce60222..cffc1ae5cd4bc2a94581da8e9acc3b5bc9735024 100644 (file)
@@ -724,7 +724,12 @@ property NAME:
         self.env_stack.pop()
         self.seen_vars_stack.pop()
         return node
-    
+
+    def visit_ComprehensionNode(self, node):
+        self.visitchildren(node)
+        node.analyse_declarations(self.env_stack[-1])
+        return node
+
     # Some nodes are no longer needed after declaration
     # analysis and can be dropped. The analysis was performed
     # on these nodes in a seperate recursive process from the
index 2e64e45f5e65a9beb30988d89450b971307d4cfa..eb1e7dbe1ce625554d24ad8e20ebbd688e0b28bc 100644 (file)
@@ -25,7 +25,6 @@ class MarkAssignments(CythonTransform):
         if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)):
             if lhs.entry is None:
                 # TODO: This shouldn't happen...
-                # It looks like comprehension loop targets are not declared soon enough.
                 return
             lhs.entry.assignments.append(rhs)
         elif isinstance(lhs, ExprNodes.SequenceNode):