Skip to content

Commit c0dc298

Browse files
committed
Support append() and delete() built-ins for type params.
Instead of interrogating the type of the slice or map expression passed to the built-in, we interrogate types of the computed built-in signature. In case of append(), it will be a slice of element types due to variadic nature of the built-in. For map it will be the plain key type. We can then use that type to translate expressing with implicit conversion.
1 parent cc4773e commit c0dc298

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

compiler/expressions.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,11 +1099,11 @@ func (fc *funcContext) translateBuiltin(name string, sig *types.Signature, args
10991099
argStr := fc.translateArgs(sig, args, ellipsis)
11001100
return fc.formatExpr("$appendSlice(%s, %s)", argStr[0], argStr[1])
11011101
}
1102-
sliceType := sig.Results().At(0).Type().Underlying().(*types.Slice)
1103-
return fc.formatExpr("$append(%e, %s)", args[0], strings.Join(fc.translateExprSlice(args[1:], sliceType.Elem()), ", "))
1102+
elType := sig.Params().At(1).Type().(*types.Slice).Elem()
1103+
return fc.formatExpr("$append(%e, %s)", args[0], strings.Join(fc.translateExprSlice(args[1:], elType), ", "))
11041104
case "delete":
11051105
args = fc.expandTupleArgs(args)
1106-
keyType := fc.pkgCtx.TypeOf(args[0]).Underlying().(*types.Map).Key()
1106+
keyType := sig.Params().At(1).Type()
11071107
return fc.formatExpr(
11081108
`$mapDelete(%1e, %2s.keyFor(%3s))`,
11091109
args[0],

tests/typeparams/builtins_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,30 @@ func TestNew(t *testing.T) {
198198
})
199199
}
200200
}
201+
202+
func _append[E any, S []E](s S, e E) S {
203+
return append(s, e)
204+
}
205+
206+
func TestAppend(t *testing.T) {
207+
got := _append([]int{1, 2}, 3)
208+
want := []int{1, 2, 3}
209+
210+
if !reflect.DeepEqual(got, want) {
211+
t.Errorf("Got: append(...) = %#v. Want: %#v", got, want)
212+
}
213+
}
214+
215+
func _delete[K comparable, M map[K]string | map[K]int](m M, k K) {
216+
delete(m, k)
217+
}
218+
219+
func TestDelete(t *testing.T) {
220+
got := map[int]string{1: "a", 2: "b"}
221+
delete(got, 1)
222+
want := map[int]string{2: "b"}
223+
224+
if !reflect.DeepEqual(got, want) {
225+
t.Errorf("Got: delete(...) = %#v. Want: %#v", got, want)
226+
}
227+
}

0 commit comments

Comments
 (0)