interp: types should not recover data for aliases
When `nodeType` recovers names and methods, it can overwrite the data if the type is an aliasT. When aliasing a type, do not recover the methods, this will be done in the GTA typeSpec pass. Related to #1158
This commit is contained in:
19
_test/alias3.go
Normal file
19
_test/alias3.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import "github.com/traefik/yaegi/_test/alias3"
|
||||
|
||||
var globalT *T
|
||||
|
||||
func init() {
|
||||
globalT = &T{A: "test"}
|
||||
}
|
||||
|
||||
type T alias3.T
|
||||
|
||||
func (t *T) PrintT() {
|
||||
(*alias3.T)(t).Print()
|
||||
}
|
||||
|
||||
func main() {
|
||||
globalT.PrintT()
|
||||
}
|
||||
12
_test/alias3/alias3.go
Normal file
12
_test/alias3/alias3.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package alias3
|
||||
|
||||
type T struct {
|
||||
A string
|
||||
}
|
||||
|
||||
func (t *T) Print() {
|
||||
println(t.A)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// test
|
||||
@@ -285,10 +285,15 @@ func (interp *Interpreter) gta(root *node, rpath, importPath, pkgName string) ([
|
||||
sym, exists := sc.sym[typeName]
|
||||
if !exists {
|
||||
sc.sym[typeName] = &symbol{kind: typeSym}
|
||||
} else if sym.typ == nil || len(sym.typ.method) == 0 {
|
||||
// TODO(mpl): figure out how to detect redeclarations without breaking type aliases.
|
||||
// Allow redeclarations for now.
|
||||
sc.sym[typeName] = &symbol{kind: typeSym}
|
||||
} else {
|
||||
if sym.typ != nil && (len(sym.typ.method) > 0) {
|
||||
// Type has already been seen as a receiver in a method function
|
||||
n.typ.method = append(n.typ.method, sym.typ.method...)
|
||||
} else {
|
||||
// TODO(mpl): figure out how to detect redeclarations without breaking type aliases.
|
||||
// Allow redeclarations for now.
|
||||
sc.sym[typeName] = &symbol{kind: typeSym}
|
||||
}
|
||||
}
|
||||
sc.sym[typeName].typ = n.typ
|
||||
if !n.typ.isComplete() {
|
||||
|
||||
@@ -888,11 +888,11 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
|
||||
err = n.cfgErrorf("use of untyped nil %s", t.name)
|
||||
}
|
||||
|
||||
if n.anc.kind == typeSpec {
|
||||
// The existing symbol data needs to be recovered, but not in the
|
||||
// case where we are aliasing another type.
|
||||
if n.anc.kind == typeSpec && n.kind != selectorExpr && n.kind != identExpr {
|
||||
name := n.anc.child[0].ident
|
||||
if sym := sc.sym[name]; sym != nil {
|
||||
// Recover previously declared methods and set the type name.
|
||||
t.method = sym.typ.method
|
||||
t.path = sc.pkgName
|
||||
t.name = name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user