diff options
Diffstat (limited to 'src/cmd/compile/testdata/script')
| -rw-r--r-- | src/cmd/compile/testdata/script/issue73947.txt | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/cmd/compile/testdata/script/issue73947.txt b/src/cmd/compile/testdata/script/issue73947.txt new file mode 100644 index 0000000000..f888ae2bfa --- /dev/null +++ b/src/cmd/compile/testdata/script/issue73947.txt @@ -0,0 +1,125 @@ +go build main.go +! stdout . +! stderr . + +-- main.go -- + +package main + +import ( + "p/b" +) + +func main() { + f() +} + +func f() { + typ := indexedPageType{newIndexedType(nil)} + page := newPage(typ.indexedType) + page.Data() +} + +func newPage(typ *indexedType) Page { + values := typ.NewValues(nil, nil) + return &indexedPage{ + typ: typ, + values: values.Int32(), + columnIndex: ^0, + } +} + +type Type interface { + NewPage(columnIndex, numValues int, data b.Values) Page + NewValues(values []byte, offsets []uint32) b.Values +} + +type Page interface { + Type() Type + Data() b.Values +} + +type indexedPage struct { + typ *indexedType + values []int32 + columnIndex int16 +} + +func (page *indexedPage) Type() Type { return indexedPageType{page.typ} } + +func (page *indexedPage) Data() b.Values { return b.Int32Values(page.values) } + +type indexedType struct { + Type +} + +func newIndexedType(typ Type) *indexedType { + return &indexedType{Type: typ} +} + +type indexedPageType struct{ *indexedType } + +func (t indexedPageType) NewValues(values []byte, _ []uint32) b.Values { + return b.Int32ValuesFromBytes(values) +} + +-- go.mod -- +module p + +go 1.24 + +-- internal/a/a.go -- +package a + +import "unsafe" + +type slice struct { + ptr unsafe.Pointer + len int + cap int +} + +func Slice[To, From any](data []From) []To { + // This function could use unsafe.Slice but it would drop the capacity + // information, so instead we implement the type conversion. + var zf From + var zt To + var s = slice{ + ptr: unsafe.Pointer(unsafe.SliceData(data)), + len: int((uintptr(len(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)), + cap: int((uintptr(cap(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)), + } + return *(*[]To)(unsafe.Pointer(&s)) +} + +-- b/b.go -- +package b + +import "p/internal/a" + +type Kind int32 + +const Int32 Kind = iota + 2 + +type Values struct { + kind Kind + size int32 + data []byte + offsets []uint32 +} + +func (v *Values) Int32() []int32 { + return a.Slice[int32](v.data) +} + +func makeValues[T any](kind Kind, values []T) Values { + return Values{kind: kind, data: a.Slice[byte](values)} +} + +func Int32Values(values []int32) Values { + return makeValues(Int32, values) +} + +func Int32ValuesFromBytes(values []byte) Values { + return Values{kind: Int32, data: values} +} |
