mirror of https://github.com/golang/go.git
cmd/compile: clean up encoding of method expressions and add test
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>
This commit is contained in:
parent
e9407ae514
commit
aff4889089
|
|
@ -1157,9 +1157,9 @@ func (p *exporter) expr(n *Node) {
|
||||||
// Special case: name used as local variable in export.
|
// Special case: name used as local variable in export.
|
||||||
// _ becomes ~b%d internally; print as _ for export
|
// _ becomes ~b%d internally; print as _ for export
|
||||||
if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
|
if n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
|
||||||
// case 0: mapped to ONAME
|
// case 0: mapped to OPACK
|
||||||
p.op(ONAME)
|
p.op(OPACK)
|
||||||
p.bool(true) // indicate blank identifier
|
p.string("_") // inlined and customized version of p.sym(n)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1174,22 +1174,18 @@ func (p *exporter) expr(n *Node) {
|
||||||
// but for export, this should be rendered as (*pkg.T).meth.
|
// 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.
|
// 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 {
|
if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
|
||||||
// case 2: mapped to ONAME
|
// case 2: mapped to OXDOT
|
||||||
p.op(ONAME)
|
p.op(OXDOT)
|
||||||
// TODO(gri) can we map this case directly to OXDOT
|
p.expr(n.Left) // n.Left.Op == OTYPE
|
||||||
// and then get rid of the bool here?
|
|
||||||
p.bool(false) // indicate non-blank identifier
|
|
||||||
p.typ(n.Left.Type)
|
|
||||||
p.fieldSym(n.Right.Sym, true)
|
p.fieldSym(n.Right.Sym, true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// case 3: mapped to OPACK
|
// case 3: mapped to OPACK
|
||||||
p.op(OPACK)
|
fallthrough
|
||||||
p.sym(n) // fallthrough inlined here
|
|
||||||
|
|
||||||
case OPACK, ONONAME:
|
case OPACK, ONONAME:
|
||||||
p.op(op)
|
p.op(OPACK)
|
||||||
p.sym(n)
|
p.sym(n)
|
||||||
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
|
|
@ -1508,6 +1504,8 @@ func (p *exporter) fieldSym(s *Sym, short bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
func (p *exporter) sym(n *Node) {
|
||||||
s := n.Sym
|
s := n.Sym
|
||||||
if s.Pkg != nil {
|
if s.Pkg != nil {
|
||||||
|
|
|
||||||
|
|
@ -798,15 +798,10 @@ func (p *importer) node() *Node {
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ONAME:
|
// case ONAME, OPACK, ONONAME:
|
||||||
if p.bool() {
|
// unreachable - mapped to case OPACK below by exporter
|
||||||
// "_"
|
|
||||||
// TODO(gri) avoid repeated "_" lookup
|
|
||||||
return mkname(Pkglookup("_", localpkg))
|
|
||||||
}
|
|
||||||
return NodSym(OXDOT, typenod(p.typ()), p.fieldSym())
|
|
||||||
|
|
||||||
case OPACK, ONONAME:
|
case OPACK:
|
||||||
return mkname(p.sym())
|
return mkname(p.sym())
|
||||||
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
// 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
|
||||||
Loading…
Reference in New Issue