mirror of
https://github.com/golang/go
synced 2024-11-22 02:14:40 -07:00
gc: bug250, bug251 - recursive interface types
Fixes #287. R=ken2 CC=golang-dev https://golang.org/cl/199057
This commit is contained in:
parent
a3372bd655
commit
44898c7b76
@ -853,7 +853,10 @@ stotype(NodeList *l, int et, Type **t)
|
||||
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) {
|
||||
|
@ -122,10 +122,61 @@ walkdeflist(NodeList *l)
|
||||
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;
|
||||
@ -214,40 +265,21 @@ walkdef(Node *n)
|
||||
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;
|
||||
}
|
||||
intypedef++;
|
||||
if(intypedef > 1)
|
||||
deftypequeue = list(deftypequeue, n);
|
||||
else {
|
||||
walkdeftype(n);
|
||||
while(deftypequeue != nil) {
|
||||
NodeList *l;
|
||||
|
||||
// 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");
|
||||
l = deftypequeue;
|
||||
deftypequeue = nil;
|
||||
for(; l; l=l->next)
|
||||
walkdeftype(l->n);
|
||||
}
|
||||
}
|
||||
intypedef--;
|
||||
break;
|
||||
|
||||
case OPACK:
|
||||
|
@ -19,9 +19,9 @@ type I4 interface {
|
||||
}
|
||||
|
||||
type I5 interface {
|
||||
I6
|
||||
I6 // ERROR "interface"
|
||||
}
|
||||
|
||||
type I6 interface {
|
||||
I5 // ERROR "interface"
|
||||
I5
|
||||
}
|
||||
|
19
test/fixedbugs/bug250.go
Normal file
19
test/fixedbugs/bug250.go
Normal file
@ -0,0 +1,19 @@
|
||||
// $G $D/$F.go || echo BUG: bug250
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
type I1 interface {
|
||||
m() I2
|
||||
}
|
||||
|
||||
type I2 interface {
|
||||
I1
|
||||
}
|
||||
|
||||
var i1 I1 = i2
|
||||
var i2 I2
|
||||
var i2a I2 = i1
|
21
test/fixedbugs/bug251.go
Normal file
21
test/fixedbugs/bug251.go
Normal file
@ -0,0 +1,21 @@
|
||||
// errchk $G $D/$F.go
|
||||
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
type I1 interface {
|
||||
m() I2
|
||||
I2 // ERROR "loop"
|
||||
}
|
||||
|
||||
type I2 interface {
|
||||
I1
|
||||
}
|
||||
|
||||
|
||||
var i1 I1 = i2
|
||||
var i2 I2
|
||||
var i2a I2 = i1
|
Loading…
Reference in New Issue
Block a user