-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed as not planned
Description
This is a TinyGo bug where slices.Grow allocates more capacity than requested. While Go's spec says Grow increases capacity by "at least n", both implementations should behave consistently for code that relies on the exact capacity returned.
func TestSlicesGrow(t *testing.T) {
var s []int
s = slices.Grow(s, 1)
t.Logf("cap after Grow(nil, 1): %d", cap(s))
if cap(s) != 1 {
t.Errorf("cap is %d, expected 1", cap(s))
}
}Result:
go test ./dns && tinygo test ./dns
ok github.com/soypat/lneto-bug/dns 0.001s
--- FAIL: TestSlicesGrow (0.00s)
cap after Grow(nil, 1): 2
cap is 2, expected 1
FAIL
FAIL github.com/soypat/lneto-bug/dns 0.000s
A even more reduced implementation of the bug:
func TestAppendSpread(t *testing.T) {
s := append([]int(nil), make([]int, 1)...)
if cap(s) != 1 {
t.Errorf("cap is %d, expected 1", cap(s))
}
}According to Claude:
Root cause: TinyGo's append with spread operator (...) doesn't optimize for exact capacity when appending a known-size slice to nil.
Go recognizes this pattern and allocates exactly the needed capacity, while TinyGo applies its growth strategy (doubling), resulting in cap=2 instead of cap=1. This is a TinyGo compiler/runtime bug in how it handles append with the spread operator.
Metadata
Metadata
Assignees
Labels
No labels