diff options
| author | Dan Scales <danscales@google.com> | 2021-03-10 17:27:30 -0800 |
|---|---|---|
| committer | Dan Scales <danscales@google.com> | 2021-03-12 02:30:33 +0000 |
| commit | e87c4bb3ef9d1f0aee3c9cc9fec8bef7fcadd6d8 (patch) | |
| tree | 76cff111a81f0d20e311cce87f2bee892e446737 /src/cmd/compile/internal/noder | |
| parent | 71330963c080960f2f398fcd711a1fa14f68d503 (diff) | |
| download | go-e87c4bb3ef9d1f0aee3c9cc9fec8bef7fcadd6d8.tar.xz | |
cmd/compile: fix noder.Addr() to not call typechecker
Simple change to avoid calling the old typechecker in noder.Addr(). This
fixes cases where generic code calls a pointer method with a non-pointer
receiver.
Added test typeparam/lockable.go that now works with this change.
For lockable.go to work, also fix incorrect check to decide whether to
translate an OXDOT now or later. We should delay translating an OXDOT
until instantiation (because we don't know how embedding, etc. will
work) if the receiver has any typeparam, not just if the receiver type
is a simple typeparam. We also have to handle OXDOT for now in
IsAddressable(), until we can remove calls to the old typechecker in
(*irgen).funcBody().
Change-Id: I77ee5efcef9a8f6c7133564106a32437e36ba4bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/300990
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/expr.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/helpers.go | 9 |
2 files changed, 7 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go index 06aa91199c..989ebf236e 100644 --- a/src/cmd/compile/internal/noder/expr.go +++ b/src/cmd/compile/internal/noder/expr.go @@ -188,7 +188,7 @@ func (g *irgen) expr0(typ types2.Type, expr syntax.Expr) ir.Node { // than in typecheck.go. func (g *irgen) selectorExpr(pos src.XPos, typ types2.Type, expr *syntax.SelectorExpr) ir.Node { x := g.expr(expr.X) - if x.Type().Kind() == types.TTYPEPARAM { + if x.Type().HasTParam() { // Leave a method call on a type param as an OXDOT, since it can // only be fully transformed once it has an instantiated type. n := ir.NewSelectorExpr(pos, ir.OXDOT, x, typecheck.Lookup(expr.Sel.Value)) diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go index 4cb6bc3eab..2b084ff311 100644 --- a/src/cmd/compile/internal/noder/helpers.go +++ b/src/cmd/compile/internal/noder/helpers.go @@ -54,8 +54,11 @@ func Nil(pos src.XPos, typ *types.Type) ir.Node { // Expressions func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr { - // TODO(mdempsky): Avoid typecheck.Expr. Probably just need to set OPTRLIT when appropriate. - n := typecheck.Expr(typecheck.NodAddrAt(pos, x)).(*ir.AddrExpr) + n := typecheck.NodAddrAt(pos, x) + switch x.Op() { + case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT: + n.SetOp(ir.OPTRLIT) + } typed(types.NewPtr(x.Type()), n) return n } @@ -125,7 +128,7 @@ func Call(pos src.XPos, typ *types.Type, fun ir.Node, args []ir.Node, dots bool) n.IsDDD = dots if fun.Op() == ir.OXDOT { - if fun.(*ir.SelectorExpr).X.Type().Kind() != types.TTYPEPARAM { + if !fun.(*ir.SelectorExpr).X.Type().HasTParam() { base.FatalfAt(pos, "Expecting type param receiver in %v", fun) } // For methods called in a generic function, don't do any extra |
