Add code to fix up iterators.
@@ -2135,6 +2135,7 @@ infernode(Node **np, Type *ret, int *sawret)
unify(n, e, b);
else
htput(seqbase, t, e);
+ delayedcheck(n, curstab());
break;
case Nmatchstmt:
infernode(&n->matchstmt.val, NULL, sawret);
@@ -2378,6 +2379,35 @@ checkvar(Node *n, Node ***rem, size_t *nrem, Stab ***remscope, size_t *nremscope
unify(n, type(n), ty);
}
+static void
+fixiter(Node *n, Type *ty, Type *base)
+{
+ size_t i, bestidx;
+ int r, bestrank;
+ Type *b, *t;
+
+ ty = tysearch(ty);
+ b = htget(seqbase, ty);
+ if (!b)
+ return;
+ bestrank = -1;
+ bestidx = 0;
+ for (i = 0; i < nimpltab; i++) {
+ if (impltab[i]->impl.trait != traittab[Tciter])
+ continue;
+ r = tymatchrank(impltab[i]->impl.type, ty);
+ if (r > bestrank) {
+ bestrank = r;
+ bestidx = i;
+ }
+ }
+ if (bestrank >= 0) {
+ t = tf(impltab[bestidx]->impl.aux[0]);
+ t = tyfreshen(NULL, t);
+ unify(n, t, base);
+ }
+}
+
static void
postcheckpass(Node ***rem, size_t *nrem, Stab ***remscope, size_t *nremscope)
{
@@ -2387,6 +2417,7 @@ postcheckpass(Node ***rem, size_t *nrem, Stab ***remscope, size_t *nremscope)
for (i = 0; i < npostcheck; i++) {
n = postcheck[i];
pushstab(postcheckscope[i]);
+ if (n->type == Nexpr) {
switch (exprop(n)) {
case Omemb: infercompn(n, rem, nrem, remscope, nremscope); break;
case Ocast: checkcast(n, rem, nrem, remscope, nremscope); break;
@@ -2394,6 +2425,9 @@ postcheckpass(Node ***rem, size_t *nrem, Stab ***remscope, size_t *nremscope)
case Ovar: checkvar(n, rem, nrem, remscope, nremscope); break;
default: die("should not see %s in postcheck\n", opstr[exprop(n)]);
}
+ } else if (n->type == Niterstmt) {
+ fixiter(n, type(n->iterstmt.seq), type(n->iterstmt.elt));
+ }
popstab();
}
}
@@ -2419,7 +2453,6 @@ postinfer(void)
postcheckscope = remscope;
npostcheckscope = nremscope;
}
- postcheckpass(NULL, NULL, NULL, NULL);
}
/* After inference, replace all
@@ -2876,6 +2909,9 @@ initimpl(void)
pushenv(impl->impl.env);
ty = tf(impl->impl.type);
addtraittab(traitmap, tr, ty);
+ if (tr->uid == Tciter) {
+ htput(seqbase, tf(impl->impl.type), tf(impl->impl.aux[0]));
+ }
popenv(impl->impl.env);
}
popstab();
