Description
Discovered by way of #60676, our shallow importer loses the canonical identity of forwarded fields:
package foo
type Foo struct { F int }
---
package bar
type Bar Foo
---
package baz
var _ = Bar{ F: 2 }
In this example, when we import bar.Bar
, we build its underlying. However, since we have not imported foo
in the same importer, we do not get the same exact type for struct { F int }
, because it doesn't exist in the type index. Therefore, the importer creates a new field.
I believe this is only a problem for forwarded fields and forwarded interface methods. It is not a problem for concrete methods or embedded interfaces.
I am going to make a quick-and-dirty fix for references (using position in our objectPath algorithm 😵 ...), but we really want to avoid duplication of these objects.
A longer term solution could be:
- keep track of the current decl when exporting
- when exporting a field or interface method whose package differs from the current decl's package, instead of encoding the field itself, encode its package and objectpath
- in the importer, use objectpath.Object to look up the corresponding canonical field
Unfortunately, this doesn't work for instantiated fields:
type Bar Foo[int]
In this case, there's nothing we can do to create a correct field. We'd want to set its origin, but there is no types.Var.SetOrigin
method (or constructor), and no way to know which instance produced a given field :(
Activity
gopherbot commentedon Jun 19, 2023
Change https://go.dev/cl/503438 mentions this issue:
internal/gcimporter: supporting encoding objects from different packages
internal/gcimporter: supporting encoding objects from different packages