This program panics inside reflect, after CL 681937.

package main

import "reflect"

type W struct {
    E struct{}
    X *byte
}

func main() {
    w := reflect.ValueOf(W{})
    _ = w.Field(0).Interface()
}
panic: bad indir

goroutine 1 [running]:
reflect.packEface({0x100b2a740?, 0x0?, 0x0?})
    /Users/khr/sandbox/tip/src/reflect/value.go:130 +0xa0
reflect.valueInterface({0x100b2a740?, 0x0?, 0x100ba02c8?}, 0xc0?)
    /Users/khr/sandbox/tip/src/reflect/value.go:1506 +0x9c
reflect.Value.Interface(...)
    /Users/khr/sandbox/tip/src/reflect/value.go:1484
main.main()
    /Users/khr/gowork/tmp8.go:12 +0x64
exit status 2

The problem is that we have a value which can be stored directly in an interface. In this case, it is a value of type W. We then ask for its first field, which gets us a zero-sized value. We need to not mark that value as being direct, as it isn't pointer shaped. This was not possible pre- CL 681937, because only structs with a single pointer field were considered direct. In that case, directness can always be inherited. No longer.

Comment From: gopherbot

Change https://go.dev/cl/694195 mentions this issue: reflect: handle zero-sized fields of directly-stored structures correctly

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)