avoid a type assertion panic with generic code

I was wrongly assumed that, if `used` has an `Elem` method,
then `origin` must too. But it does not if it's a type parameter.

Add a test case too, which panicked before the fix.

Fixes #577.
pull/581/head
Daniel Martí 2 years ago
parent 8ad374d2fb
commit 9d46fe917a

@ -5,6 +5,7 @@
This bugfix release continues support for Go 1.18 and 1.19.
* Fix an edge case resulting in bad syntax due to comments - [#573]
* Avoid a panic involving generic code - [#577]
## [v0.7.1] - 2022-08-02
@ -144,6 +145,7 @@ Known bugs:
* `garble test` is temporarily disabled, as it is currently broken
[#573]: https://github.com/burrowers/garble/issues/573
[#577]: https://github.com/burrowers/garble/issues/577
[v0.7.1]: https://github.com/burrowers/garble/releases/tag/v0.7.1

@ -1385,8 +1385,13 @@ func (tf *transformer) recordType(used, origin types.Type) {
type Container interface{ Elem() types.Type }
switch used := used.(type) {
case Container:
origin := origin.(Container)
tf.recordType(used.Elem(), origin.Elem())
// origin may be a *types.TypeParam, which is not a Container.
// For now, we haven't found a need to recurse in that case.
// We can edit this code in the future if we find an example,
// because we panic if a field is not in fieldToStruct.
if origin, ok := origin.(Container); ok {
tf.recordType(used.Elem(), origin.Elem())
}
case *types.Named:
if tf.recordTypeDone[used] {
return

@ -15,8 +15,11 @@ func main() {
GenericFunc[int, int](1, 2)
var _ GenericVector[int]
g := GenericGraph[string]{Content: "Foo"}
g.Edges = make([]GenericGraph[string], 1)
g1 := GenericGraph[string]{Content: "Foo"}
g1.Edges = make([]GenericGraph[string], 1)
g2 := GenericGraph[*[]byte]{Content: new([]byte)}
g2.Edges = make([]GenericGraph[*[]byte], 1)
}
func GenericFunc[GenericParamA, B any](x GenericParamA, y B) {}
@ -44,3 +47,9 @@ type CombineEmbeds interface {
interface { EmbeddedMethod() }
RegularMethod()
}
type Slice[T any] []T
func sliceOfPointer() Slice[*any] {
return []*any{}
}

Loading…
Cancel
Save