Skip to content

cmd/compile: package path of distinct types with unexported fields is the same #16616

@icza

Description

@icza

Go version and environment:
go version go1.6.3 windows/amd64

Issue:
If we have an exported function in a package, which has a parameter of anonymous struct type with unexported fields, e.g.:

package subplay

import "fmt"

func PrintAnonymous(v struct{ i int }) {
    fmt.Printf("PrintAnonymous: %d\n", v.i)
}

We can't call this function from another package, trying to pass an anonymous struct value (with matching fields), e.g.:

value := struct{ i int }{1}
subplay.PrintAnonymous(value)

We get a compile-time error:

cannot use value (type struct { i int }) as type struct { i int } in argument to subplay.PrintAnonymous

Understandable, as the fields of the anonymous struct are unexported.

It is also understandable that we can use reflection to create a zero value of this type, and call subplay.PrintAnonymous() with this:

v := reflect.ValueOf(subplay.PrintAnonymous)
paramt := v.Type().In(0)
v.Call([]reflect.Value{reflect.New(paramt).Elem()})

Which runs, and doesn't panic.

But now if I try to pass a reflect.Value of a value of my own anonymous struct (with matching, unexported fields), with non-zero values, it still runs without panic:

value := struct{ i int }{1}
v := reflect.ValueOf(subplay.PrintAnonymous)
v.Call([]reflect.Value{reflect.ValueOf(value)})

My question: is this normal? If yes, then this should be possible without using reflection, too. If without reflection the compile-time error is justified, then using reflection should result in runtime panic.

Inspired by this StackOverflow question.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions