aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2020-12-26 18:56:36 -0800
committerMatthew Dempsky <mdempsky@google.com>2020-12-28 07:44:07 +0000
commite6c973198d9f8e68e4dce8637e2d1492032ce939 (patch)
treeeabf85d6087243281a55a98983db4e11b7803fb5 /src/cmd/compile/internal/typecheck
parent135ce1c485d0563d285f47a748a6d56594571a91 (diff)
downloadgo-e6c973198d9f8e68e4dce8637e2d1492032ce939.tar.gz
go-e6c973198d9f8e68e4dce8637e2d1492032ce939.zip
[dev.regabi] cmd/compile: stop mangling SelectorExpr.Sel for ODOTMETH
ODOTMETH is unique among SelectorExpr expressions, in that Sel gets mangled so that it no longer has the original identifier that was selected (e.g., just "Foo"), but instead the qualified symbol name for the selected method (e.g., "pkg.Type.Foo"). This is rarely useful, and instead results in a lot of compiler code needing to worry about undoing this change. This CL changes ODOTMETH to leave the original symbol in place. The handful of code locations where the mangled symbol name is actually wanted are updated to use ir.MethodExprName(n).Sym() or (equivalently) ir.MethodExprName(n).Func.Sym() instead. Historically, the compiler backend has mistakenly used types.Syms where it should have used ir.Name/ir.Funcs. And this change in particular may risk breaking something, as the SelectorExpr.Sel will no longer point at a symbol that uniquely identifies the called method. However, I expect CL 280294 (desugar OCALLMETH into OCALLFUNC) to have substantially reduced this risk, as ODOTMETH expressions are now replaced entirely earlier in the compiler. Passes toolstash -cmp. Change-Id: If3c9c3b7df78ea969f135840574cf89e1d263876 Reviewed-on: https://go-review.googlesource.com/c/go/+/280436 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/typecheck')
-rw-r--r--src/cmd/compile/internal/typecheck/expr.go8
-rw-r--r--src/cmd/compile/internal/typecheck/func.go29
-rw-r--r--src/cmd/compile/internal/typecheck/iexport.go22
-rw-r--r--src/cmd/compile/internal/typecheck/typecheck.go1
4 files changed, 18 insertions, 42 deletions
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
index 879ae385c7..3e7a880c2a 100644
--- a/src/cmd/compile/internal/typecheck/expr.go
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -571,7 +571,6 @@ func tcDot(n *ir.SelectorExpr, top int) ir.Node {
}
n.X = typecheck(n.X, ctxExpr|ctxType)
-
n.X = DefaultLit(n.X, nil)
t := n.X.Type()
@@ -581,8 +580,6 @@ func tcDot(n *ir.SelectorExpr, top int) ir.Node {
return n
}
- s := n.Sel
-
if n.X.Op() == ir.OTYPE {
return typecheckMethodExpr(n)
}
@@ -629,7 +626,10 @@ func tcDot(n *ir.SelectorExpr, top int) ir.Node {
}
if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && top&ctxCallee == 0 {
- return tcCallPart(n, s)
+ // Create top-level function.
+ fn := makepartialcall(n)
+
+ return ir.NewCallPartExpr(n.Pos(), n.X, n.Selection, fn)
}
return n
}
diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go
index fdac719ad9..50f514a6db 100644
--- a/src/cmd/compile/internal/typecheck/func.go
+++ b/src/cmd/compile/internal/typecheck/func.go
@@ -249,7 +249,9 @@ var globClosgen int32
// makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
// for partial calls.
-func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.Func {
+func makepartialcall(dot *ir.SelectorExpr) *ir.Func {
+ t0 := dot.Type()
+ meth := dot.Sel
rcvrtype := dot.X.Type()
sym := ir.MethodSymSuffix(rcvrtype, meth, "-fm")
@@ -263,11 +265,10 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.
ir.CurFunc = nil
// Set line number equal to the line number where the method is declared.
- var m *types.Field
- if lookdot0(meth, rcvrtype, &m, false) == 1 && m.Pos.IsKnown() {
- base.Pos = m.Pos
+ if pos := dot.Selection.Pos; pos.IsKnown() {
+ base.Pos = pos
}
- // Note: !m.Pos.IsKnown() happens for method expressions where
+ // Note: !dot.Selection.Pos.IsKnown() happens for method expressions where
// the method is implicitly declared. The Error method of the
// built-in error type is one such method. We leave the line
// number at the use of the method expression in this
@@ -280,6 +281,7 @@ func makepartialcall(dot *ir.SelectorExpr, t0 *types.Type, meth *types.Sym) *ir.
fn := DeclFunc(sym, tfn)
fn.SetDupok(true)
fn.SetNeedctxt(true)
+ fn.SetWrapper(true)
// Declare and initialize variable holding receiver.
cr := ir.NewClosureRead(rcvrtype, types.Rnd(int64(types.PtrSize), int64(rcvrtype.Align)))
@@ -382,23 +384,6 @@ func tcClosure(clo *ir.ClosureExpr, top int) {
Target.Decls = append(Target.Decls, fn)
}
-func tcCallPart(n ir.Node, sym *types.Sym) *ir.CallPartExpr {
- switch n.Op() {
- case ir.ODOTINTER, ir.ODOTMETH:
- break
-
- default:
- base.Fatalf("invalid typecheckpartialcall")
- }
- dot := n.(*ir.SelectorExpr)
-
- // Create top-level function.
- fn := makepartialcall(dot, dot.Type(), sym)
- fn.SetWrapper(true)
-
- return ir.NewCallPartExpr(dot.Pos(), dot.X, dot.Selection, fn)
-}
-
// type check function definition
// To be called by typecheck, not directly.
// (Call typecheckFunc instead.)
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index 449d99266d..0c813a71ef 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -594,23 +594,15 @@ func (w *exportWriter) selector(s *types.Sym) {
base.Fatalf("missing currPkg")
}
- // Method selectors are rewritten into method symbols (of the
- // form T.M) during typechecking, but we want to write out
- // just the bare method name.
- name := s.Name
- if i := strings.LastIndex(name, "."); i >= 0 {
- name = name[i+1:]
- } else {
- pkg := w.currPkg
- if types.IsExported(name) {
- pkg = types.LocalPkg
- }
- if s.Pkg != pkg {
- base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
- }
+ pkg := w.currPkg
+ if types.IsExported(s.Name) {
+ pkg = types.LocalPkg
+ }
+ if s.Pkg != pkg {
+ base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
}
- w.string(name)
+ w.string(s.Name)
}
func (w *exportWriter) typ(t *types.Type) {
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 1d070507fa..b779f9ceb0 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -1297,7 +1297,6 @@ func lookdot(n *ir.SelectorExpr, t *types.Type, dostrcmp int) *types.Field {
return nil
}
- n.Sel = ir.MethodSym(n.X.Type(), f2.Sym)
n.Selection = f2
n.SetType(f2.Type)
n.SetOp(ir.ODOTMETH)