interp: preserve concrete type when converting type to interface
This allows to fix the reassignment of an non empty interface value.
Before, reassignment was limited to empty interfaces.
Fixes #1138.
This commit is contained in:
@@ -5,8 +5,18 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type T struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
func (t *T) Read(p []byte) (n int, err error) { n, err = t.r.Read(p); return }
|
||||
|
||||
func main() {
|
||||
x := io.LimitedReader{}
|
||||
y := io.Reader(&x)
|
||||
fmt.Println(y)
|
||||
y = &T{y}
|
||||
fmt.Println(y.Read([]byte("")))
|
||||
}
|
||||
|
||||
// Output:
|
||||
// 0 EOF
|
||||
|
||||
@@ -930,9 +930,12 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
|
||||
if !c1.typ.implements(c0.typ) {
|
||||
err = n.cfgErrorf("type %v does not implement interface %v", c1.typ.id(), c0.typ.id())
|
||||
}
|
||||
// Pass value as is
|
||||
// Convert type to interface while keeping a reference to the original concrete type.
|
||||
// besides type, the node value remains preserved.
|
||||
n.gen = nop
|
||||
n.typ = c1.typ
|
||||
t := *c0.typ
|
||||
n.typ = &t
|
||||
n.typ.val = c1.typ
|
||||
n.findex = c1.findex
|
||||
n.level = c1.level
|
||||
n.val = c1.val
|
||||
|
||||
Reference in New Issue
Block a user