Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
1734cb02
Commit
1734cb02
authored
Feb 18, 2010
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gc: recursive interface embedding
Fixes #287. R=ken2 CC=golang-dev
https://golang.org/cl/215048
parent
cf015fd0
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
76 additions
and
40 deletions
+76
-40
dcl.c
src/cmd/gc/dcl.c
+27
-17
go.h
src/cmd/gc/go.h
+2
-0
typecheck.c
src/cmd/gc/typecheck.c
+1
-1
walk.c
src/cmd/gc/walk.c
+43
-5
bug250.go
test/fixedbugs/bug250.go
+0
-0
bug251.go
test/fixedbugs/bug251.go
+3
-3
golden.out
test/golden.out
+0
-14
No files found.
src/cmd/gc/dcl.c
View file @
1734cb02
...
@@ -809,23 +809,33 @@ stotype(NodeList *l, int et, Type **t)
...
@@ -809,23 +809,33 @@ stotype(NodeList *l, int et, Type **t)
if
(
n
->
op
!=
ODCLFIELD
)
if
(
n
->
op
!=
ODCLFIELD
)
fatal
(
"stotype: oops %N
\n
"
,
n
);
fatal
(
"stotype: oops %N
\n
"
,
n
);
if
(
n
->
right
!=
N
)
{
if
(
n
->
right
!=
N
)
{
typecheck
(
&
n
->
right
,
Etype
);
if
(
et
==
TINTER
&&
n
->
left
!=
N
)
{
n
->
type
=
n
->
right
->
type
;
// queue resolution of method type for later.
if
(
n
->
type
==
T
)
{
// right now all we need is the name list.
*
t0
=
T
;
// avoids cycles for recursive interface types.
return
t0
;
n
->
type
=
typ
(
TINTERMETH
);
}
n
->
type
->
nod
=
n
->
right
;
if
(
n
->
left
!=
N
)
n
->
right
=
N
;
n
->
left
->
type
=
n
->
type
;
queuemethod
(
n
);
n
->
right
=
N
;
}
else
{
if
(
n
->
embedded
&&
n
->
type
!=
T
)
{
typecheck
(
&
n
->
right
,
Etype
);
t1
=
n
->
type
;
n
->
type
=
n
->
right
->
type
;
if
(
t1
->
sym
==
S
&&
isptr
[
t1
->
etype
])
if
(
n
->
type
==
T
)
{
t1
=
t1
->
type
;
*
t0
=
T
;
if
(
isptr
[
t1
->
etype
])
return
t0
;
yyerror
(
"embedded type cannot be a pointer"
);
}
else
if
(
t1
->
etype
==
TFORW
&&
t1
->
embedlineno
==
0
)
if
(
n
->
left
!=
N
)
t1
->
embedlineno
=
lineno
;
n
->
left
->
type
=
n
->
type
;
n
->
right
=
N
;
if
(
n
->
embedded
&&
n
->
type
!=
T
)
{
t1
=
n
->
type
;
if
(
t1
->
sym
==
S
&&
isptr
[
t1
->
etype
])
t1
=
t1
->
type
;
if
(
isptr
[
t1
->
etype
])
yyerror
(
"embedded type cannot be a pointer"
);
else
if
(
t1
->
etype
==
TFORW
&&
t1
->
embedlineno
==
0
)
t1
->
embedlineno
=
lineno
;
}
}
}
}
}
...
...
src/cmd/gc/go.h
View file @
1734cb02
...
@@ -462,6 +462,7 @@ enum
...
@@ -462,6 +462,7 @@ enum
// pseudo-type for frame layout
// pseudo-type for frame layout
TFUNCARGS
,
TFUNCARGS
,
TCHANARGS
,
TCHANARGS
,
TINTERMETH
,
NTYPE
,
NTYPE
,
};
};
...
@@ -1088,6 +1089,7 @@ Node* typecheckconv(Node*, Node*, Type*, int, char*);
...
@@ -1088,6 +1089,7 @@ Node* typecheckconv(Node*, Node*, Type*, int, char*);
int
checkconv
(
Type
*
,
Type
*
,
int
,
int
*
,
int
*
,
char
*
);
int
checkconv
(
Type
*
,
Type
*
,
int
,
int
*
,
int
*
,
char
*
);
Node
*
typecheck
(
Node
**
,
int
);
Node
*
typecheck
(
Node
**
,
int
);
int
islvalue
(
Node
*
);
int
islvalue
(
Node
*
);
void
queuemethod
(
Node
*
);
/*
/*
* const.c
* const.c
...
...
src/cmd/gc/typecheck.c
View file @
1734cb02
...
@@ -51,7 +51,7 @@ typecheck(Node **np, int top)
...
@@ -51,7 +51,7 @@ typecheck(Node **np, int top)
int
et
,
op
;
int
et
,
op
;
Node
*
n
,
*
l
,
*
r
;
Node
*
n
,
*
l
,
*
r
;
NodeList
*
args
;
NodeList
*
args
;
int
lno
,
ok
,
ntop
,
ct
;
int
lno
,
ok
,
ntop
;
Type
*
t
;
Type
*
t
;
Sym
*
sym
;
Sym
*
sym
;
Val
v
;
Val
v
;
...
...
src/cmd/gc/walk.c
View file @
1734cb02
...
@@ -115,11 +115,25 @@ gettype(Node **np, NodeList **init)
...
@@ -115,11 +115,25 @@ gettype(Node **np, NodeList **init)
dump
(
"after gettype"
,
*
np
);
dump
(
"after gettype"
,
*
np
);
}
}
void
static
int
nwalkdeftype
;
walkdeflist
(
NodeList
*
l
)
static
NodeList
*
methodqueue
;
static
void
domethod
(
Node
*
n
)
{
{
for
(;
l
;
l
=
l
->
next
)
Node
*
nt
;
walkdef
(
l
->
n
);
nt
=
n
->
type
->
nod
;
typecheck
(
&
nt
,
Etype
);
if
(
nt
->
type
==
T
)
{
// type check failed; leave empty func
n
->
type
->
etype
=
TFUNC
;
n
->
type
->
nod
=
N
;
return
;
}
*
n
->
type
=
*
nt
->
type
;
n
->
type
->
nod
=
N
;
checkwidth
(
n
->
type
);
}
}
static
void
static
void
...
@@ -127,7 +141,9 @@ walkdeftype(Node *n)
...
@@ -127,7 +141,9 @@ walkdeftype(Node *n)
{
{
int
maplineno
,
embedlineno
,
lno
;
int
maplineno
,
embedlineno
,
lno
;
Type
*
t
;
Type
*
t
;
NodeList
*
l
;
nwalkdeftype
++
;
lno
=
lineno
;
lno
=
lineno
;
setlineno
(
n
);
setlineno
(
n
);
n
->
type
->
sym
=
n
->
sym
;
n
->
type
->
sym
=
n
->
sym
;
...
@@ -168,6 +184,28 @@ walkdeftype(Node *n)
...
@@ -168,6 +184,28 @@ walkdeftype(Node *n)
ret:
ret:
lineno
=
lno
;
lineno
=
lno
;
// if there are no type definitions going on, it's safe to
// try to resolve the method types for the interfaces
// we just read.
if
(
nwalkdeftype
==
1
)
{
while
((
l
=
methodqueue
)
!=
nil
)
{
methodqueue
=
nil
;
for
(;
l
;
l
=
l
->
next
)
domethod
(
l
->
n
);
}
}
nwalkdeftype
--
;
}
void
queuemethod
(
Node
*
n
)
{
if
(
nwalkdeftype
==
0
)
{
domethod
(
n
);
return
;
}
methodqueue
=
list
(
methodqueue
,
n
);
}
}
void
void
...
...
test/bugs/bug250.go
→
test/
fixed
bugs/bug250.go
View file @
1734cb02
File moved
test/bugs/bug251.go
→
test/
fixed
bugs/bug251.go
View file @
1734cb02
...
@@ -8,14 +8,14 @@ package main
...
@@ -8,14 +8,14 @@ package main
type
I1
interface
{
type
I1
interface
{
m
()
I2
m
()
I2
I2
// ERROR "loop|interface"
I2
}
}
type
I2
interface
{
type
I2
interface
{
I1
I1
// ERROR "loop|interface"
}
}
var
i1
I1
=
i2
var
i1
I1
=
i2
// ERROR "need type assertion"
var
i2
I2
var
i2
I2
var
i2a
I2
=
i1
var
i2a
I2
=
i1
test/golden.out
View file @
1734cb02
...
@@ -150,17 +150,3 @@ throw: interface conversion
...
@@ -150,17 +150,3 @@ throw: interface conversion
panic PC=xxx
panic PC=xxx
== bugs/
== bugs/
=========== bugs/bug250.go
bugs/bug250.go:14: interface type loop involving I1
bugs/bug250.go:17: need type assertion to use I2 as I1
missing m() I2
BUG: bug250
=========== bugs/bug251.go
BUG: errchk: bugs/bug251.go:11: missing expected error: 'loop|interface'
errchk: bugs/bug251.go: unmatched error messages:
==================================================
bugs/bug251.go:15: interface type loop involving I1
bugs/bug251.go:19: need type assertion to use I2 as I1
==================================================
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment