fix: correctly init variables from index expressions

This commit is contained in:
Traefiker Bot
2020-03-05 14:28:06 +01:00
committed by GitHub
parent 2edd18a0c0
commit 0ace9244c4
5 changed files with 86 additions and 14 deletions

20
_test/type18.go Normal file
View File

@@ -0,0 +1,20 @@
package main
type T struct {
name string
size int
}
var table = []*T{{
name: "foo",
size: 2,
}}
var s = table[0].size
func main() {
println(s)
}
// Output:
// 2

21
_test/type19.go Normal file
View File

@@ -0,0 +1,21 @@
package main
type T struct {
name string
size int
}
var table = map[int]*T{
0: {
name: "foo",
size: 2,
}}
var s = table[0].size
func main() {
println(s)
}
// Output:
// 2

View File

@@ -840,7 +840,7 @@ func (interp *Interpreter) cfg(root *node, pkgID string) ([]*node, error) {
n.findex = sc.add(n.typ)
}
// TODO: Check that composite literal expr matches corresponding type
n.gen = compositeGenerator(n)
n.gen = compositeGenerator(n, sc)
case fallthroughtStmt:
if n.anc.kind != caseBody {
@@ -1869,21 +1869,32 @@ func gotoLabel(s *symbol) {
}
}
func compositeGenerator(n *node) (gen bltnGenerator) {
func compositeGenerator(n *node, sc *scope) (gen bltnGenerator) {
switch n.typ.cat {
case aliasT, ptrT:
n.typ.val.untyped = n.typ.untyped
n.typ = n.typ.val
gen = compositeGenerator(n)
gen = compositeGenerator(n, sc)
case arrayT:
gen = arrayLit
case mapT:
gen = mapLit
case structT:
if len(n.child) > 0 && n.lastChild().kind == keyValueExpr {
gen = compositeSparse
} else {
gen = compositeLit
switch {
case len(n.child) == 0:
gen = compositeLitNotype
case n.lastChild().kind == keyValueExpr:
if n.child[0].isType(sc) {
gen = compositeSparse
} else {
gen = compositeSparseNotype
}
default:
if n.child[0].isType(sc) {
gen = compositeLit
} else {
gen = compositeLitNotype
}
}
case valueT:
switch k := n.typ.rtype.Kind(); k {
@@ -1895,7 +1906,7 @@ func compositeGenerator(n *node) (gen bltnGenerator) {
log.Panic(n.cfgErrorf("compositeGenerator not implemented for type kind: %s", k))
}
}
return
return gen
}
// arrayTypeLen returns the node's array length. If the expression is an

View File

@@ -1680,12 +1680,12 @@ func destType(n *node) *itype {
}
}
// compositeLit creates and populates a struct object
func compositeLit(n *node) {
// doCompositeLit creates and populates a struct object
func doCompositeLit(n *node, hasType bool) {
value := valueGenerator(n, n.findex)
next := getExec(n.tnext)
child := n.child
if !n.typ.untyped {
if hasType {
child = n.child[1:]
}
destInterface := destType(n).cat == interfaceT
@@ -1717,12 +1717,15 @@ func compositeLit(n *node) {
}
}
// compositeSparse creates a struct Object, filling fields from sparse key-values
func compositeSparse(n *node) {
func compositeLit(n *node) { doCompositeLit(n, true) }
func compositeLitNotype(n *node) { doCompositeLit(n, false) }
// doCompositeSparse creates a struct Object, filling fields from sparse key-values
func doCompositeSparse(n *node, hasType bool) {
value := valueGenerator(n, n.findex)
next := getExec(n.tnext)
child := n.child
if !n.typ.untyped {
if hasType {
child = n.child[1:]
}
@@ -1752,6 +1755,9 @@ func compositeSparse(n *node) {
}
}
func compositeSparse(n *node) { doCompositeSparse(n, true) }
func compositeSparseNotype(n *node) { doCompositeSparse(n, false) }
func empty(n *node) {}
var rat = reflect.ValueOf((*[]rune)(nil)).Type().Elem() // runes array type

View File

@@ -406,6 +406,20 @@ func nodeType(interp *Interpreter, sc *scope, n *node) (*itype, error) {
sc.sym[n.ident] = &symbol{kind: typeSym, typ: t}
}
case indexExpr:
var lt *itype
if lt, err = nodeType(interp, sc, n.child[0]); err != nil {
return nil, err
}
if lt.incomplete {
t.incomplete = true
break
}
switch lt.cat {
case arrayT, mapT:
t = lt.val
}
case interfaceType:
t.cat = interfaceT
if sname := typeName(n); sname != "" {