Commits

Antonio Cuni committed a5b5795

(arigo, romain, antocuni) aaargh. enumerate did not convert the repr of the items, resulting in a lot of confusion if you enumerate a list of instances, leading to incorrect C code. Fix it, and add a sanity check inside rtuple.newtuple

Comments (0)

Files changed (3)

pypy/rpython/lltypesystem/rtuple.py

 
     def newtuple(cls, llops, r_tuple, items_v):
         # items_v should have the lowleveltype of the internal reprs
+        assert len(r_tuple.items_r) == len(items_v)
+        for r_item, v_item in zip(r_tuple.items_r, items_v):
+            assert r_item.lowleveltype == v_item.concretetype
+        #
         if len(r_tuple.items_r) == 0:
             return inputconst(Void, ())    # a Void empty tuple
         c1 = inputconst(Void, r_tuple.lowleveltype.TO)

pypy/rpython/rrange.py

         v_index = hop.gendirectcall(self.ll_getnextindex, v_enumerate)
         hop2 = hop.copy()
         hop2.args_r = [self.r_baseiter]
+        r_item_src = self.r_baseiter.r_list.external_item_repr
+        r_item_dst = hop.r_result.items_r[1]
         v_item = self.r_baseiter.rtype_next(hop2)
+        v_item = hop.llops.convertvar(v_item, r_item_src, r_item_dst)
         return hop.r_result.newtuple(hop.llops, hop.r_result,
                                      [v_index, v_item])
 

pypy/rpython/test/test_rrange.py

         res = self.interpret(fn, [2])
         assert res == 789
 
+    def test_enumerate_instances(self):
+        class A:
+            pass
+        def fn(n):
+            a = A()
+            b = A()
+            a.k = 10
+            b.k = 20
+            for i, x in enumerate([a, b]):
+                if i == n:
+                    return x.k
+            return 5
+        res = self.interpret(fn, [1])
+        assert res == 20
+
+
 
 class TestLLtype(BaseTestRrange, LLRtypeMixin):
     from pypy.rpython.lltypesystem import rrange