1
0
mirror of https://github.com/golang/go synced 2024-11-22 22:20:03 -07:00

cmd/compile/internal/typecheck: prune some useless code

This error checking code is all obsolete by types2.

Change-Id: I247cee2c847236dfbd5a878441ad712481692927
Reviewed-on: https://go-review.googlesource.com/c/go/+/520607
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Matthew Dempsky 2023-08-17 23:01:42 -07:00 committed by Gopher Robot
parent 89eb6b76ae
commit 2a47bc9e4f

View File

@ -8,7 +8,6 @@ import (
"fmt"
"go/constant"
"go/token"
"internal/types/errors"
"strings"
"cmd/compile/internal/base"
@ -152,39 +151,6 @@ func typekind(t *types.Type) string {
return fmt.Sprintf("etype=%d", et)
}
func cycleFor(start ir.Node) []ir.Node {
// Find the start node in typecheck_tcstack.
// We know that it must exist because each time we mark
// a node with n.SetTypecheck(2) we push it on the stack,
// and each time we mark a node with n.SetTypecheck(2) we
// pop it from the stack. We hit a cycle when we encounter
// a node marked 2 in which case is must be on the stack.
i := len(typecheck_tcstack) - 1
for i > 0 && typecheck_tcstack[i] != start {
i--
}
// collect all nodes with same Op
var cycle []ir.Node
for _, n := range typecheck_tcstack[i:] {
if n.Op() == start.Op() {
cycle = append(cycle, n)
}
}
return cycle
}
func cycleTrace(cycle []ir.Node) string {
var s string
for i, n := range cycle {
s += fmt.Sprintf("\n\t%v: %v uses %v", ir.Line(n), n, cycle[(i+1)%len(cycle)])
}
return s
}
var typecheck_tcstack []ir.Node
// typecheck type checks node n.
// The result of typecheck MUST be assigned back to n, e.g.
//
@ -200,6 +166,7 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
}
lno := ir.SetPos(n)
defer func() { base.Pos = lno }()
// Skip over parens.
for n.Op() == ir.OPAREN {
@ -214,103 +181,18 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
break
default:
base.Pos = lno
return n
}
}
if n.Typecheck() == 2 {
// Typechecking loop. Trying printing a meaningful message,
// otherwise a stack trace of typechecking.
switch n.Op() {
// We can already diagnose variables used as types.
case ir.ONAME:
n := n.(*ir.Name)
if top&(ctxExpr|ctxType) == ctxType {
base.Errorf("%v is not a type", n)
}
case ir.OTYPE:
// Only report a type cycle if we are expecting a type.
// Otherwise let other code report an error.
if top&ctxType == ctxType {
// A cycle containing only alias types is an error
// since it would expand indefinitely when aliases
// are substituted.
cycle := cycleFor(n)
for _, n1 := range cycle {
if n1.Name() != nil && !n1.Name().Alias() {
// Cycle is ok. But if n is an alias type and doesn't
// have a type yet, we have a recursive type declaration
// with aliases that we can't handle properly yet.
// Report an error rather than crashing later.
if n.Name() != nil && n.Name().Alias() && n.Type() == nil {
base.Pos = n.Pos()
base.Fatalf("cannot handle alias type declaration (issue #25838): %v", n)
}
base.Pos = lno
return n
}
}
base.ErrorfAt(n.Pos(), errors.InvalidDeclCycle, "invalid recursive type alias %v%s", n, cycleTrace(cycle))
}
case ir.OLITERAL:
if top&(ctxExpr|ctxType) == ctxType {
base.Errorf("%v is not a type", n)
break
}
base.ErrorfAt(n.Pos(), errors.InvalidInitCycle, "constant definition loop%s", cycleTrace(cycleFor(n)))
}
if base.Errors() == 0 {
var trace string
for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
x := typecheck_tcstack[i]
trace += fmt.Sprintf("\n\t%v %v", ir.Line(x), x)
}
base.Errorf("typechecking loop involving %v%s", n, trace)
}
base.Pos = lno
return n
base.FatalfAt(n.Pos(), "typechecking loop")
}
typecheck_tcstack = append(typecheck_tcstack, n)
n.SetTypecheck(2)
n = typecheck1(n, top)
n.SetTypecheck(1)
last := len(typecheck_tcstack) - 1
typecheck_tcstack[last] = nil
typecheck_tcstack = typecheck_tcstack[:last]
_, isExpr := n.(ir.Expr)
_, isStmt := n.(ir.Stmt)
isMulti := false
switch n.Op() {
case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
n := n.(*ir.CallExpr)
if t := n.X.Type(); t != nil && t.Kind() == types.TFUNC {
nr := t.NumResults()
isMulti = nr > 1
if nr == 0 {
isExpr = false
}
}
case ir.OAPPEND, ir.OMIN, ir.OMAX:
// Must be used.
isStmt = false
case ir.OCLEAR, ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN:
// Must not be used.
isExpr = false
isStmt = true
case ir.OCOPY, ir.ORECOVER, ir.ORECV:
// Can be used or not.
isStmt = true
}
t := n.Type()
if t != nil && !t.IsFuncArgStruct() && n.Op() != ir.OTYPE {
switch t.Kind() {
@ -323,25 +205,6 @@ func typecheck(n ir.Node, top int) (res ir.Node) {
}
}
// TODO(rsc): Lots of the complexity here is because typecheck can
// see OTYPE, ONAME, and OLITERAL nodes multiple times.
// Once we make the IR a proper tree, we should be able to simplify
// this code a bit, especially the final case.
switch {
case top&(ctxStmt|ctxExpr) == ctxExpr && !isExpr && n.Op() != ir.OTYPE && !isMulti:
base.Fatalf("%v used as value", n)
case top&ctxType == 0 && n.Op() == ir.OTYPE && t != nil:
base.Fatalf("type %v is not an expression", n.Type())
case top&(ctxStmt|ctxExpr) == ctxStmt && !isStmt && t != nil:
base.Fatalf("%v evaluated but not used", n)
case top&(ctxType|ctxExpr) == ctxType && n.Op() != ir.OTYPE && n.Op() != ir.ONONAME && (t != nil || n.Op() == ir.ONAME):
base.Fatalf("%v is not a type", n)
}
base.Pos = lno
return n
}