Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Kirill Smelkov
go
Commits
1734cb02
Commit
1734cb02
authored
15 years ago
by
Russ Cox
Browse files
Options
Download
Email Patches
Plain Diff
gc: recursive interface embedding
Fixes #287. R=ken2 CC=golang-dev
https://golang.org/cl/215048
parent
cf015fd0
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
76 additions
and
40 deletions
+76
-40
src/cmd/gc/dcl.c
src/cmd/gc/dcl.c
+27
-17
src/cmd/gc/go.h
src/cmd/gc/go.h
+2
-0
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+1
-1
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+43
-5
test/fixedbugs/bug250.go
test/fixedbugs/bug250.go
+0
-0
test/fixedbugs/bug251.go
test/fixedbugs/bug251.go
+3
-3
test/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)
if
(
n
->
op
!=
ODCLFIELD
)
fatal
(
"stotype: oops %N
\n
"
,
n
);
if
(
n
->
right
!=
N
)
{
typecheck
(
&
n
->
right
,
Etype
);
n
->
type
=
n
->
right
->
type
;
if
(
n
->
type
==
T
)
{
*
t0
=
T
;
return
t0
;
}
if
(
n
->
left
!=
N
)
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
;
if
(
et
==
TINTER
&&
n
->
left
!=
N
)
{
// queue resolution of method type for later.
// right now all we need is the name list.
// avoids cycles for recursive interface types.
n
->
type
=
typ
(
TINTERMETH
);
n
->
type
->
nod
=
n
->
right
;
n
->
right
=
N
;
queuemethod
(
n
);
}
else
{
typecheck
(
&
n
->
right
,
Etype
);
n
->
type
=
n
->
right
->
type
;
if
(
n
->
type
==
T
)
{
*
t0
=
T
;
return
t0
;
}
if
(
n
->
left
!=
N
)
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
;
}
}
}
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/go.h
View file @
1734cb02
...
...
@@ -462,6 +462,7 @@ enum
// pseudo-type for frame layout
TFUNCARGS
,
TCHANARGS
,
TINTERMETH
,
NTYPE
,
};
...
...
@@ -1088,6 +1089,7 @@ Node* typecheckconv(Node*, Node*, Type*, int, char*);
int
checkconv
(
Type
*
,
Type
*
,
int
,
int
*
,
int
*
,
char
*
);
Node
*
typecheck
(
Node
**
,
int
);
int
islvalue
(
Node
*
);
void
queuemethod
(
Node
*
);
/*
* const.c
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/typecheck.c
View file @
1734cb02
...
...
@@ -51,7 +51,7 @@ typecheck(Node **np, int top)
int
et
,
op
;
Node
*
n
,
*
l
,
*
r
;
NodeList
*
args
;
int
lno
,
ok
,
ntop
,
ct
;
int
lno
,
ok
,
ntop
;
Type
*
t
;
Sym
*
sym
;
Val
v
;
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/walk.c
View file @
1734cb02
...
...
@@ -115,11 +115,25 @@ gettype(Node **np, NodeList **init)
dump
(
"after gettype"
,
*
np
);
}
void
walkdeflist
(
NodeList
*
l
)
static
int
nwalkdeftype
;
static
NodeList
*
methodqueue
;
static
void
domethod
(
Node
*
n
)
{
for
(;
l
;
l
=
l
->
next
)
walkdef
(
l
->
n
);
Node
*
nt
;
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
...
...
@@ -127,7 +141,9 @@ walkdeftype(Node *n)
{
int
maplineno
,
embedlineno
,
lno
;
Type
*
t
;
NodeList
*
l
;
nwalkdeftype
++
;
lno
=
lineno
;
setlineno
(
n
);
n
->
type
->
sym
=
n
->
sym
;
...
...
@@ -168,6 +184,28 @@ walkdeftype(Node *n)
ret:
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
...
...
This diff is collapsed.
Click to expand it.
test/bugs/bug250.go
→
test/
fixed
bugs/bug250.go
View file @
1734cb02
File moved
This diff is collapsed.
Click to expand it.
test/bugs/bug251.go
→
test/
fixed
bugs/bug251.go
View file @
1734cb02
...
...
@@ -8,14 +8,14 @@ package main
type
I1
interface
{
m
()
I2
I2
// ERROR "loop|interface"
I2
}
type
I2
interface
{
I1
I1
// ERROR "loop|interface"
}
var
i1
I1
=
i2
var
i1
I1
=
i2
// ERROR "need type assertion"
var
i2
I2
var
i2a
I2
=
i1
This diff is collapsed.
Click to expand it.
test/golden.out
View file @
1734cb02
...
...
@@ -150,17 +150,3 @@ throw: interface conversion
panic PC=xxx
== 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
==================================================
This diff is collapsed.
Click to expand it.
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