]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: more incremental typecheck for unified IR
authorMatthew Dempsky <mdempsky@google.com>
Sat, 10 Jul 2021 00:47:15 +0000 (17:47 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Sat, 10 Jul 2021 04:02:52 +0000 (04:02 +0000)
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>
src/cmd/compile/internal/noder/codes.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go

index 4a6a4e83071be58ad55dd7d64c87c67f7d4d218e..f8cb7729acc2287a13f626d9ab8ce495701b6711 100644 (file)
@@ -107,9 +107,7 @@ const (
        exprUnaryOp
        exprBinaryOp
        exprCall
-
-       // TODO(mdempsky): Handle in switchStmt directly instead.
-       exprTypeSwitchGuard
+       exprConvert
 )
 
 type codeDecl int
index 122bc70f24bf5a78c93563b0c2fb4fc755a5ee9f..19e51d9eba90764a116604969d72ac96e191b8df 100644 (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)
        }
 }
 
index 6348a5674148a13ec1756538f98c8cfff13de5ba..3f9310514a4b693e55629883a1aa3d5798047144 100644 (file)
@@ -1033,7 +1033,17 @@ func (w *writer) switchStmt(stmt *syntax.SwitchStmt) {
        w.openScope(stmt.Pos())
        w.pos(stmt)
        w.stmt(stmt.Init)
-       w.expr(stmt.Tag)
+
+       if guard, ok := stmt.Tag.(*syntax.TypeSwitchGuard); w.bool(ok) {
+               w.pos(guard)
+               if tag := guard.Lhs; w.bool(tag != nil) {
+                       w.pos(tag)
+                       w.string(tag.Value)
+               }
+               w.expr(guard.X)
+       } else {
+               w.expr(stmt.Tag)
+       }
 
        w.len(len(stmt.Body))
        for i, clause := range stmt.Body {
@@ -1207,6 +1217,19 @@ func (w *writer) expr(expr syntax.Expr) {
                w.expr(expr.Y)
 
        case *syntax.CallExpr:
+               tv, ok := w.p.info.Types[expr.Fun]
+               assert(ok)
+               if tv.IsType() {
+                       assert(len(expr.ArgList) == 1)
+                       assert(!expr.HasDots)
+
+                       w.code(exprConvert)
+                       w.typ(tv.Type)
+                       w.pos(expr)
+                       w.expr(expr.ArgList[0])
+                       break
+               }
+
                w.code(exprCall)
 
                if inf, ok := w.p.info.Inferred[expr]; ok {
@@ -1223,15 +1246,6 @@ func (w *writer) expr(expr syntax.Expr) {
                w.pos(expr)
                w.exprs(expr.ArgList)
                w.bool(expr.HasDots)
-
-       case *syntax.TypeSwitchGuard:
-               w.code(exprTypeSwitchGuard)
-               w.pos(expr)
-               if tag := expr.Lhs; w.bool(tag != nil) {
-                       w.pos(tag)
-                       w.string(tag.Value)
-               }
-               w.expr(expr.X)
        }
 }