Fixes #15646.
Change-Id: Ic13d1adc0a358149209195cdb03811eeee506fb8
Reviewed-on: https://go-review.googlesource.com/23052
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
// Special case: name used as local variable in export.
// _ becomes ~b%d internally; print as _ for export
if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
- // case 0: mapped to ONAME
- p.op(ONAME)
- p.bool(true) // indicate blank identifier
+ // case 0: mapped to OPACK
+ p.op(OPACK)
+ p.string("_") // inlined and customized version of p.sym(n)
break
}
// but for export, this should be rendered as (*pkg.T).meth.
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
- // case 2: mapped to ONAME
- p.op(ONAME)
- // TODO(gri) can we map this case directly to OXDOT
- // and then get rid of the bool here?
- p.bool(false) // indicate non-blank identifier
- p.typ(n.Left.Type)
+ // case 2: mapped to OXDOT
+ p.op(OXDOT)
+ p.expr(n.Left) // n.Left.Op == OTYPE
p.fieldSym(n.Right.Sym, true)
break
}
// case 3: mapped to OPACK
- p.op(OPACK)
- p.sym(n) // fallthrough inlined here
+ fallthrough
case OPACK, ONONAME:
- p.op(op)
+ p.op(OPACK)
p.sym(n)
case OTYPE:
}
}
+// sym must encode the _ (blank) identifier as a single string "_" since
+// encoding for some nodes is based on this assumption (e.g. ONAME nodes).
func (p *exporter) sym(n *Node) {
s := n.Sym
if s.Pkg != nil {
}
return n
- case ONAME:
- if p.bool() {
- // "_"
- // TODO(gri) avoid repeated "_" lookup
- return mkname(Pkglookup("_", localpkg))
- }
- return NodSym(OXDOT, typenod(p.typ()), p.fieldSym())
+ // case ONAME, OPACK, ONONAME:
+ // unreachable - mapped to case OPACK below by exporter
- case OPACK, ONONAME:
+ case OPACK:
return mkname(p.sym())
case OTYPE:
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type T struct{}
+
+func (T) m() string {
+ return "m"
+}
+
+func (*T) mp() string {
+ return "mp"
+}
+
+func F() func(T) string {
+ return T.m // method expression
+}
+
+func Fp() func(*T) string {
+ return (*T).mp // method expression
+}
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "./a" // import must succeed
+
+func main() {
+ if a.F()(a.T{}) != "m" {
+ panic(0)
+ }
+ if a.Fp()(nil) != "mp" {
+ panic(1)
+ }
+}
--- /dev/null
+// rundir
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that method expressions are correctly encoded
+// in binary export data and can be imported again.
+package ignore
\ No newline at end of file