if(et == TINTER && n->left == N) {
// embedded interface - inline the methods
if(n->type->etype != TINTER) {
- yyerror("interface contains embedded non-interface %T", n->type);
+ if(n->type->etype == TFORW)
+ yyerror("interface type loop involving %T", n->type);
+ else
+ yyerror("interface contains embedded non-interface %T", n->type);
continue;
}
for(t1=n->type->type; t1!=T; t1=t1->down) {
walkdef(l->n);
}
+static NodeList *deftypequeue;
+static int intypedef;
+
+static void
+walkdeftype(Node *n)
+{
+ int maplineno, embedlineno, lno;
+ Type *t;
+
+ lno = lineno;
+ setlineno(n);
+ n->type->sym = n->sym;
+ n->typecheck = 1;
+ typecheck(&n->ntype, Etype);
+ if((t = n->ntype->type) == T) {
+ n->diag = 1;
+ goto ret;
+ }
+
+ // copy new type and clear fields
+ // that don't come along
+ maplineno = n->type->maplineno;
+ embedlineno = n->type->embedlineno;
+ *n->type = *t;
+ t = n->type;
+ t->sym = n->sym;
+ t->local = n->local;
+ t->vargen = n->vargen;
+ t->siggen = 0;
+ t->printed = 0;
+ t->method = nil;
+ t->nod = N;
+ t->printed = 0;
+ t->deferwidth = 0;
+
+ // double-check use of type as map key
+ // TODO(rsc): also use of type as receiver?
+ if(maplineno) {
+ lineno = maplineno;
+ maptype(n->type, types[TBOOL]);
+ }
+ if(embedlineno) {
+ lineno = embedlineno;
+ if(isptr[t->etype])
+ yyerror("embedded type cannot be a pointer");
+ }
+
+ret:
+ lineno = lno;
+}
+
void
walkdef(Node *n)
{
- int lno, maplineno, embedlineno;
+ int lno;
NodeList *init;
Node *e;
Type *t;
n->walkdef = 1;
n->type = typ(TFORW);
n->type->sym = n->sym;
- n->typecheck = 1;
- typecheck(&n->ntype, Etype);
- if((t = n->ntype->type) == T) {
- n->diag = 1;
- goto ret;
- }
-
- // copy new type and clear fields
- // that don't come along
- maplineno = n->type->maplineno;
- embedlineno = n->type->embedlineno;
- *n->type = *t;
- t = n->type;
- t->sym = n->sym;
- t->local = n->local;
- t->vargen = n->vargen;
- t->siggen = 0;
- t->printed = 0;
- t->method = nil;
- t->nod = N;
- t->printed = 0;
- t->deferwidth = 0;
-
- // double-check use of type as map key
- // TODO(rsc): also use of type as receiver?
- if(maplineno) {
- lineno = maplineno;
- maptype(n->type, types[TBOOL]);
- }
- if(embedlineno) {
- lineno = embedlineno;
- if(isptr[t->etype])
- yyerror("embedded type cannot be a pointer");
+ intypedef++;
+ if(intypedef > 1)
+ deftypequeue = list(deftypequeue, n);
+ else {
+ walkdeftype(n);
+ while(deftypequeue != nil) {
+ NodeList *l;
+
+ l = deftypequeue;
+ deftypequeue = nil;
+ for(; l; l=l->next)
+ walkdeftype(l->n);
+ }
}
+ intypedef--;
break;
case OPACK: