diff --git a/cl/compile.go b/cl/compile.go index 4f602c2c..9f2e9ceb 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -418,9 +418,6 @@ func (p *context) compileVArg(ret []llssa.Expr, b llssa.Builder, v ssa.Value) [] switch v := v.(type) { case *ssa.Slice: // varargs: this is a varargs slice if args, ok := p.isVArgs(v.X); ok { - for i, arg := range args { - args[i] = arg.Do(true) - } return append(ret, args...) } case *ssa.Const: @@ -435,7 +432,7 @@ func (p *context) compileValues(b llssa.Builder, vals []ssa.Value, hasVArg int) n := len(vals) - hasVArg ret := make([]llssa.Expr, n) for i := 0; i < n; i++ { - ret[i] = p.compileValue(b, vals[i]).Do(false) + ret[i] = p.compileValue(b, vals[i]).Do() } if hasVArg > 0 { ret = p.compileVArg(ret, b, vals[n]) diff --git a/ssa/expr.go b/ssa/expr.go index 932ae445..811d6d06 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -42,33 +42,25 @@ func (v Expr) TypeOf() types.Type { */ // Do evaluates the delay expression and returns the result. -func (v Expr) Do(isVArg bool) Expr { +func (v Expr) Do() Expr { if vt := v.Type; vt.kind == vkDelayExpr { - delay := vt.t.(*delayExprTy) - if f := delay.f; f != nil { - delay.f = nil - delay.val = f(isVArg) - } - return delay.val + return vt.t.(delayExprTy)() } return v } // DelayExpr returns a delay expression. -func DelayExpr(f func(isVArg bool) Expr) Expr { - return Expr{Type: &aType{t: &delayExprTy{f: f}, kind: vkDelayExpr}} +func DelayExpr(f func() Expr) Expr { + return Expr{Type: &aType{t: delayExprTy(f), kind: vkDelayExpr}} } -type delayExprTy struct { - f func(isVArg bool) Expr - val Expr -} +type delayExprTy func() Expr -func (p *delayExprTy) Underlying() types.Type { +func (p delayExprTy) Underlying() types.Type { panic("don't call") } -func (p *delayExprTy) String() string { +func (p delayExprTy) String() string { return "delayExpr" } @@ -461,10 +453,7 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp } t := inter.Underlying().(*types.Interface) isAny := t.Empty() - fnDo := func(isVArg bool) Expr { - if isVArg { // don't need make interface - return x - } + fnDo := func() Expr { pkg := b.fn.pkg switch x.kind { case vkSigned, vkUnsigned, vkFloat: @@ -476,7 +465,7 @@ func (b Builder) MakeInterface(inter types.Type, x Expr, mayDelay bool) (ret Exp if mayDelay && isAny { return DelayExpr(fnDo) } - return fnDo(false) + return fnDo() } // The TypeAssert instruction tests whether interface value X has type diff --git a/ssa/package.go b/ssa/package.go index 5410a302..23af1d23 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -195,6 +195,7 @@ func (p Program) Bool() Type { return p.boolTy } +// Any returns any type. func (p Program) Any() Type { if p.anyTy == nil { p.anyTy = p.Type(tyAny) diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 448515bf..c6977054 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -23,6 +23,37 @@ import ( "testing" ) +/* +func TestMakeInterface(t *testing.T) { + var b Builder + b.MakeInterface(types.NewInterfaceType(nil, nil), Expr{}, true).Do(true) +} +*/ + +func TestDelayExpr(t *testing.T) { + a := delayExprTy(nil) + _ = a.String() + defer func() { + if r := recover(); r == nil { + t.Log("TestDelayExpr: no error?") + } + }() + a.Underlying() +} + +func TestAny(t *testing.T) { + prog := NewProgram(nil) + prog.SetRuntime(func() *types.Package { + ret := types.NewPackage("runtime", "runtime") + scope := ret.Scope() + name := types.NewTypeName(0, ret, "Interface", nil) + types.NewNamed(name, types.NewStruct(nil, nil), nil) + scope.Insert(name) + return ret + }) + prog.Any() +} + func assertPkg(t *testing.T, p Package, expected string) { t.Helper() if v := p.String(); v != expected {