compiler: properly inline methods, use receiver

Notice that this doesn't differentiate between (*T) and (T) receivers always
treating them as is. But we have the same problem with arguments now and the
number of inlined calls is limited, usually we want this behavior.
This commit is contained in:
Roman Khimov 2022-07-06 17:56:53 +03:00
parent 6014dd720f
commit b57dd2cad6
3 changed files with 38 additions and 0 deletions

View file

@ -55,6 +55,15 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
copy(newScope, c.scope.vars.locals)
defer c.scope.vars.dropScope()
if f.decl.Recv != nil {
c.scope.vars.locals = newScope
name := f.decl.Recv.List[0].Names[0].Name
c.scope.vars.addAlias(name, -1, unspecifiedVarIndex, &varContext{
importMap: c.importMap,
expr: f.selector,
scope: oldScope,
})
}
hasVarArgs := !n.Ellipsis.IsValid()
needPack := sig.Variadic() && hasVarArgs
for i := range n.Args {

View file

@ -336,3 +336,22 @@ func TestPackageVarsInInlinedCalls(t *testing.T) {
}`
eval(t, src, big.NewInt(13))
}
func TestInlinedMethod(t *testing.T) {
src := `package foo
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/inline"
func Main() int {
// It's important for this variable to not be named 't'.
var z inline.T
i := z.Inc(42)
if i != 0 || z.N != 42 {
return 0
}
i = z.Inc(100500)
if i != 42 {
return 0
}
return z.N
}`
eval(t, src, big.NewInt(100542))
}

View file

@ -46,3 +46,13 @@ func SumVar(a, b int) int {
func Concat(n int) int {
return n*100 + b.A*10 + A
}
type T struct {
N int
}
func (t *T) Inc(i int) int {
n := t.N
t.N += i
return n
}