Skip to content

Commit

Permalink
cl: fix compileCompositeLitEx struct for sliceLit/mapLit
Browse files Browse the repository at this point in the history
  • Loading branch information
visualfc committed Aug 3, 2024
1 parent e3757c5 commit e5e1ea9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
25 changes: 25 additions & 0 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4193,3 +4193,28 @@ func main() {
}
`)
}

func TestCompositeLitEx(t *testing.T) {
gopClTest(t, `
type T struct {
s []any
m map[any]any
}
echo &T{[10, 3.14, 200], {10: "A", 3.14: "B", 200: "C"}}
echo &T{s: [10, 3.14, 200], m: {10: "A", 3.14: "B", 200: "C"}}
`, `package main
import "fmt"
type T struct {
s []interface{}
m map[interface{}]interface{}
}
func main() {
fmt.Println(&T{[]interface{}{10, 3.14, 200}, map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}})
fmt.Println(&T{s: []interface{}{10, 3.14, 200}, m: map[interface{}]interface{}{10: "A", 3.14: "B", 200: "C"}})
}
`)
}
37 changes: 33 additions & 4 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,27 @@ func compileCompositeLitElts(ctx *blockCtx, elts []ast.Expr, kind int, expected
}
}

func compileStructLit(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
for idx, elt := range elts {
switch expr := elt.(type) {
case *ast.LambdaExpr, *ast.LambdaExpr2:
sig, err := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, elt)
if err != nil {
return err
}
compileLambda(ctx, expr, sig)

Check warning on line 1102 in cl/expr.go

View check run for this annotation

Codecov / codecov/patch

cl/expr.go#L1097-L1102

Added lines #L1097 - L1102 were not covered by tests
case *ast.SliceLit:
compileSliceLit(ctx, expr, t.Field(idx).Type())
case *ast.CompositeLit:
compileCompositeLit(ctx, expr, t.Field(idx).Type(), false)
default:
compileExpr(ctx, elt)
}
}
ctx.cb.StructLit(typ, len(elts), false, src)
return nil
}

func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, typ types.Type, src *ast.CompositeLit) error {
for _, elt := range elts {
kv := elt.(*ast.KeyValueExpr)
Expand All @@ -1112,6 +1133,10 @@ func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, t
return err
}
compileLambda(ctx, expr, sig)
case *ast.SliceLit:
compileSliceLit(ctx, expr, t.Field(idx).Type())
case *ast.CompositeLit:
compileCompositeLit(ctx, expr, t.Field(idx).Type(), false)
default:
compileExpr(ctx, kv.Value)
}
Expand Down Expand Up @@ -1194,8 +1219,14 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
typ, underlying = expected, tu
}
}
if t, ok := underlying.(*types.Struct); ok && kind == compositeLitKeyVal {
if err := compileStructLitInKeyVal(ctx, v.Elts, t, typ, v); err != nil {
if t, ok := underlying.(*types.Struct); ok {
var err error
if kind == compositeLitKeyVal {
err = compileStructLitInKeyVal(ctx, v.Elts, t, typ, v)
} else {
err = compileStructLit(ctx, v.Elts, t, typ, v)
}
if err != nil {
return err
}
} else {
Expand All @@ -1214,8 +1245,6 @@ func compileCompositeLitEx(ctx *blockCtx, v *ast.CompositeLit, expected types.Ty
ctx.cb.SliceLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
case *types.Array:
ctx.cb.ArrayLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
case *types.Struct:
ctx.cb.StructLit(typ, n, false, v) // key-val mode handled by compileStructLitInKeyVal
default:
return ctx.newCodeErrorf(v.Pos(), "invalid composite literal type %v", typ)
}
Expand Down

0 comments on commit e5e1ea9

Please sign in to comment.