[dev.typeparams] cmd/compile: more incremental typecheck for unified IR

CL 332469 changed the unified IR reader to incrementally typecheck
each statement as they're read/constructed. This CL goes further to
incrementally typecheck each expression.

While here, this CL reorganizes a few things to make this go more
smoothly. In particular, it renames expr to expr0 and adds a new expr
wrapper that applies typecheck.Expr; gets rid of exprTypeSwitchguard
by moving that logic into switchStmt; and splits exprConvert out from
exprCall, which simplifies the logic for typechecking the calleee
expression somewhat.

Change-Id: I6289de9388dc94a947971f4b7213aafeb2faa5dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/333730
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
Matthew Dempsky 2021-07-09 17:47:15 -07:00
parent a12ad27119
commit 3c3c1d8d28
3 changed files with 57 additions and 24 deletions

View file

@ -1252,7 +1252,7 @@ func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
continue
}
lhs[i] = r.expr()
lhs[i] = typecheck.AssignExpr(r.expr0())
}
return names, lhs
@ -1351,7 +1351,21 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node {
r.openScope()
pos := r.pos()
init := r.stmt()
tag := r.expr()
var tag ir.Node
if r.bool() {
pos := r.pos()
var ident *ir.Ident
if r.bool() {
pos := r.pos()
sym := typecheck.Lookup(r.string())
ident = ir.NewIdent(pos, sym)
}
x := r.expr()
tag = ir.NewTypeSwitchGuard(pos, ident, x)
} else {
tag = r.expr()
}
tswitch, ok := tag.(*ir.TypeSwitchGuard)
if ok && tswitch.Tag == nil {
@ -1432,7 +1446,19 @@ func (r *reader) initDefn(defn ir.InitNode, names []*ir.Name) bool {
// @@@ Expressions
// expr reads and returns a typechecked expression.
func (r *reader) expr() ir.Node {
n := r.expr0()
if n == nil || n.Op() == ir.OTYPE {
// TODO(mdempsky): Push this responsibility up to callers?
return n
}
return typecheck.Expr(n)
}
// expr0 reads and returns an expression, possibly untypechecked.
// The caller must typecheck the result as appropriate for its context.
func (r *reader) expr0() ir.Node {
switch tag := codeExpr(r.code(syncExpr)); tag {
default:
panic("unhandled expression")
@ -1522,22 +1548,17 @@ func (r *reader) expr() ir.Node {
return ir.NewBinaryExpr(pos, op, x, y)
case exprCall:
fun := r.expr()
fun := typecheck.Callee(r.expr0())
pos := r.pos()
args := r.exprs()
dots := r.bool()
return typecheck.Call(pos, fun, args, dots)
case exprTypeSwitchGuard:
case exprConvert:
typ := r.typ()
pos := r.pos()
var tag *ir.Ident
if r.bool() {
pos := r.pos()
sym := typecheck.Lookup(r.string())
tag = ir.NewIdent(pos, sym)
}
x := r.expr()
return ir.NewTypeSwitchGuard(pos, tag, x)
return ir.NewConvExpr(pos, ir.OCONV, typ, x)
}
}