Skip to content

Commit 9a3b3e7

Browse files
committed
cl: fix compileCompositeLitEx struct for sliceLit/mapLit
1 parent e3757c5 commit 9a3b3e7

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

cl/compile_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -4193,3 +4193,34 @@ func main() {
41934193
}
41944194
`)
41954195
}
4196+
4197+
func TestCompositeLitEx(t *testing.T) {
4198+
gopClTest(t, `
4199+
type T struct {
4200+
s []any
4201+
m map[any]any
4202+
fn func(int) int
4203+
}
4204+
4205+
echo &T{[10, 3.14, 200], {10: "A", 3.14: "B", 200: "C"}, (x => x)}
4206+
echo &T{s: [10, 3.14, 200], m: {10: "A", 3.14: "B", 200: "C"}, fn: (x => x)}
4207+
`, `package main
4208+
4209+
import "fmt"
4210+
4211+
type T struct {
4212+
s []interface{}
4213+
m map[interface{}]interface{}
4214+
fn func(int) int
4215+
}
4216+
4217+
func main() {
4218+
fmt.Println(&T{[]interface{}{10, 3.14, 200}, map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}, func(x int) int {
4219+
return x
4220+
}})
4221+
fmt.Println(&T{s: []interface{}{10, 3.14, 200}, m: map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}, fn: func(x int) int {
4222+
return x
4223+
}})
4224+
}
4225+
`)
4226+
}

cl/expr.go

+41-5
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,34 @@ func compileCompositeLitElts(ctx *blockCtx, elts []ast.Expr, kind int, expected
10911091
}
10921092
}
10931093

1094+
func unparent(x ast.Expr) ast.Expr {
1095+
if e, ok := x.(*ast.ParenExpr); ok {
1096+
return e.X
1097+
}
1098+
return x
1099+
}
1100+
1101+
func compileStructLit(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
1102+
for idx, elt := range elts {
1103+
switch expr := unparent(elt).(type) {
1104+
case *ast.LambdaExpr, *ast.LambdaExpr2:
1105+
sig, err := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, elt)
1106+
if err != nil {
1107+
return err
1108+
}
1109+
compileLambda(ctx, expr, sig)
1110+
case *ast.SliceLit:
1111+
compileSliceLit(ctx, expr, t.Field(idx).Type())
1112+
case *ast.CompositeLit:
1113+
compileCompositeLit(ctx, expr, t.Field(idx).Type(), false)
1114+
default:
1115+
compileExpr(ctx, elt)
1116+
}
1117+
}
1118+
ctx.cb.StructLit(typ, len(elts), false, src)
1119+
return nil
1120+
}
1121+
10941122
func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
10951123
for _, elt := range elts {
10961124
kv := elt.(*ast.KeyValueExpr)
@@ -1105,13 +1133,17 @@ func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, t
11051133
if rec := ctx.recorder(); rec != nil {
11061134
rec.Use(name, t.Field(idx))
11071135
}
1108-
switch expr := kv.Value.(type) {
1136+
switch expr := unparent(kv.Value).(type) {
11091137
case *ast.LambdaExpr, *ast.LambdaExpr2:
11101138
sig, err := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, kv.Key)
11111139
if err != nil {
11121140
return err
11131141
}
11141142
compileLambda(ctx, expr, sig)
1143+
case *ast.SliceLit:
1144+
compileSliceLit(ctx, expr, t.Field(idx).Type())
1145+
case *ast.CompositeLit:
1146+
compileCompositeLit(ctx, expr, t.Field(idx).Type(), false)
11151147
default:
11161148
compileExpr(ctx, kv.Value)
11171149
}
@@ -1194,8 +1226,14 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
11941226
typ, underlying = expected, tu
11951227
}
11961228
}
1197-
if t, ok := underlying.(*types.Struct); ok && kind == compositeLitKeyVal {
1198-
if err := compileStructLitInKeyVal(ctx, v.Elts, t, typ, v); err != nil {
1229+
if t, ok := underlying.(*types.Struct); ok {
1230+
var err error
1231+
if kind == compositeLitKeyVal {
1232+
err = compileStructLitInKeyVal(ctx, v.Elts, t, typ, v)
1233+
} else {
1234+
err = compileStructLit(ctx, v.Elts, t, typ, v)
1235+
}
1236+
if err != nil {
11991237
return err
12001238
}
12011239
} else {
@@ -1214,8 +1252,6 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
12141252
ctx.cb.SliceLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
12151253
case *types.Array:
12161254
ctx.cb.ArrayLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
1217-
case *types.Struct:
1218-
ctx.cb.StructLit(typ, n, false, v) // key-val mode handled by compileStructLitInKeyVal
12191255
default:
12201256
return ctx.newCodeErrorf(v.Pos(), "invalid composite literal type %v", typ)
12211257
}

cl/stmt.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ func compileAssignStmt(ctx *blockCtx, expr *ast.AssignStmt) {
295295
compileExprLHS(ctx, lhs)
296296
}
297297
for i, rhs := range expr.Rhs {
298-
switch e := rhs.(type) {
298+
switch e := unparent(rhs).(type) {
299299
case *ast.LambdaExpr, *ast.LambdaExpr2:
300300
if len(expr.Lhs) == 1 && len(expr.Rhs) == 1 {
301301
typ := ctx.cb.Get(-1).Type.(interface{ Elem() types.Type }).Elem()

0 commit comments

Comments
 (0)