]> Cypherpunks.ru repositories - gostls13.git/commitdiff
reflect: fix ArenaNew to match documentation
authorMichael Anthony Knyszek <mknyszek@google.com>
Thu, 8 Jun 2023 18:40:31 +0000 (18:40 +0000)
committerMichael Knyszek <mknyszek@google.com>
Fri, 16 Jun 2023 17:08:43 +0000 (17:08 +0000)
Currently ArenaNew expects the type passed in to be a *T and it returns
a *T. This does not match the function's documentation.

Since this is an experiment, change ArenaNew to match the documentation.
This more closely aligns ArenaNew with arena.New. (Takes a type T,
returns a *T value.)

Note that this is a breaking change. However, as far as pkg.go.dev can
tell, there's exactly one package using it in the open source world.

Also, add smoke test for the exported API, which is just a wrapper
around the internal API. Clearly there's enough room for error here that
it should be tested, but we don't need thorough tests at this layer
because that already exists in the runtime. We just need to make sure it
basically works.

Fixes #60528.

Change-Id: I673cc4609378380ef80648b0c2eb2928e73f49c9
Reviewed-on: https://go-review.googlesource.com/c/go/+/501860
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/internal/testdir/testdir_test.go
src/reflect/arena.go
test/arenas/smoke.go [new file with mode: 0644]

index f5bd44eef2d8b92cec2afd75650d41936e984a20..7ab1143584a9108d993684883e51223a5a1077e1 100644 (file)
@@ -64,7 +64,7 @@ var (
 
        // dirs are the directories to look for *.go files in.
        // TODO(bradfitz): just use all directories?
-       dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi", "typeparam", "typeparam/mdempsky"}
+       dirs = []string{".", "ken", "chan", "interface", "syntax", "dwarf", "fixedbugs", "codegen", "runtime", "abi", "typeparam", "typeparam/mdempsky", "arenas"}
 )
 
 // Test is the main entrypoint that runs tests in the GOROOT/test directory.
index 694a3a136c46814e0f8c17032b67f9c39e38f7d7..cac1a1da5eaaeff243eea1d2f2894740dbc48410 100644 (file)
@@ -12,7 +12,7 @@ import "arena"
 // specified type, allocating storage for it in the provided arena. That is,
 // the returned Value's Type is PointerTo(typ).
 func ArenaNew(a *arena.Arena, typ Type) Value {
-       return ValueOf(arena_New(a, typ))
+       return ValueOf(arena_New(a, PointerTo(typ)))
 }
 
 func arena_New(a *arena.Arena, typ any) any
diff --git a/test/arenas/smoke.go b/test/arenas/smoke.go
new file mode 100644 (file)
index 0000000..56dad53
--- /dev/null
@@ -0,0 +1,65 @@
+// build -goexperiment arenas
+
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+       "arena"
+       "log"
+       "reflect"
+)
+
+func main() {
+       a := arena.NewArena()
+       defer a.Free()
+
+       const iValue = 10
+
+       i := arena.New[int](a)
+       *i = iValue
+
+       if *i != iValue {
+               // This test doesn't reasonably expect this to fail. It's more likely
+               // that *i crashes for some reason. Still, why not check it.
+               log.Fatalf("bad i value: got %d, want %d", *i, iValue)
+       }
+
+       const wantLen = 125
+       const wantCap = 1912
+
+       sl := arena.MakeSlice[*int](a, wantLen, wantCap)
+       if len(sl) != wantLen {
+               log.Fatalf("bad arena slice length: got %d, want %d", len(sl), wantLen)
+       }
+       if cap(sl) != wantCap {
+               log.Fatalf("bad arena slice capacity: got %d, want %d", cap(sl), wantCap)
+       }
+       sl = sl[:cap(sl)]
+       for j := range sl {
+               sl[j] = i
+       }
+       for j := range sl {
+               if *sl[j] != iValue {
+                       // This test doesn't reasonably expect this to fail. It's more likely
+                       // that sl[j] crashes for some reason. Still, why not check it.
+                       log.Fatalf("bad sl[j] value: got %d, want %d", *sl[j], iValue)
+               }
+       }
+
+       t := reflect.TypeOf(int(0))
+       v := reflect.ArenaNew(a, t)
+       if want := reflect.PointerTo(t); v.Type() != want {
+               log.Fatalf("unexpected type for arena-allocated value: got %s, want %s", v.Type(), want)
+       }
+       i2 := v.Interface().(*int)
+       *i2 = iValue
+
+       if *i2 != iValue {
+               // This test doesn't reasonably expect this to fail. It's more likely
+               // that *i crashes for some reason. Still, why not check it.
+               log.Fatalf("bad i2 value: got %d, want %d", *i2, iValue)
+       }
+}