traefik / yaegi

Yaegi is Another Elegant Go Interpreter
https://pkg.go.dev/github.com/traefik/yaegi
Apache License 2.0
7.02k stars 349 forks source link

Cannot run embedded + generic code #1571

Closed zbysir closed 1 year ago

zbysir commented 1 year ago

The following program sample.go triggers an unexpected result

package main

type A struct {
    *b[string]
}

type b[T any] struct {
    data T
}

func main() {
  a := &A{
    b: &b[string]{},
  }

  _ = a
}

Expected result

// Nothing happend, it works fine.

Got

run: ./sample.go:13:3: unknown field b in struct literal

Yaegi Version

0.15.1

Additional Notes

Cannot run embedded + generic code, although they work in isolation.

zbysir commented 1 year ago

Additional Note:

Both of the following pieces of code work fine:


type A struct {
    B *B[string]
}

type B[T any] struct {
    data T
}

a := &A{
    B: &B[string]{},
}

type A struct {
    *B
}

type B struct {
}

a := &A{
    B: &B{},
}
zbysir commented 1 year ago

Maybe this "embedding" issue is related to https://github.com/traefik/yaegi/issues/1502

zbysir commented 1 year ago

This can be quickly fixed by modifying the fieldName method:

https://github.com/traefik/yaegi/blob/75e5f99bc5761d8e920e726f75932a31b6f06669/interp/type.go#L1227C1-L1238C2

func fieldName(n *node) string {
    switch n.kind {
    case selectorExpr:
        return fieldName(n.child[1])
    case starExpr:
        return fieldName(n.child[0])
    case identExpr:
        return n.ident
+   case indexExpr:
+       return fieldName(n.child[0])
    default:
        return ""
    }
}

But maybe this is not the most correct, because indexExpr seems to be the wrong kind.


Update: indexExpr is correct because go/ast is defined that way.