fix: correctly init variables from index expressions
This commit is contained in:
20
_test/type18.go
Normal file
20
_test/type18.go
Normal 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
21
_test/type19.go
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 != "" {
|
||||
|
||||
Reference in New Issue
Block a user