]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: use nil instead of syntax.ImplicitOne
authorRobert Griesemer <gri@golang.org>
Thu, 21 Jan 2021 01:03:36 +0000 (17:03 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 21 Jan 2021 06:55:47 +0000 (06:55 +0000)
Represent x++/-- as x +=/-= with the RHS of the assignment being nil
rather than syntax.ImplicitOne.

Dependent code already had to check for syntax.ImplicitOne, but
then shared some existing code for regular assignment operations.
Now always handle this case fully explicit, which simplifies the
code.

Change-Id: I28c7918153c27cbbf97b041d0c85ff027c58687c
Reviewed-on: https://go-review.googlesource.com/c/go/+/285172
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/noder/expr.go
src/cmd/compile/internal/noder/noder.go
src/cmd/compile/internal/noder/stmt.go
src/cmd/compile/internal/syntax/nodes.go
src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/printer.go
src/cmd/compile/internal/syntax/walk.go
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/pos.go
src/cmd/compile/internal/types2/stmt.go

index be592003e18b55870797209f0f4462d7141b8a8c..76db774229e9b2b787c06f8b7543e0a7c855c084 100644 (file)
@@ -19,10 +19,6 @@ func (g *irgen) expr(expr syntax.Expr) ir.Node {
                return nil
        }
 
-       if expr == syntax.ImplicitOne {
-               base.Fatalf("expr of ImplicitOne")
-       }
-
        if expr, ok := expr.(*syntax.Name); ok && expr.Value == "_" {
                return ir.BlankNode
        }
index 0c7d0159773005664973f21957c540a8fcc8e0d2..e1ae2569e0c97a149853b06cb506c117d94ca487 100644 (file)
@@ -677,11 +677,7 @@ func (p *noder) expr(expr syntax.Expr) ir.Node {
        case *syntax.Name:
                return p.mkname(expr)
        case *syntax.BasicLit:
-               pos := base.Pos
-               if expr != syntax.ImplicitOne { // ImplicitOne doesn't have a unique position
-                       pos = p.pos(expr)
-               }
-               n := ir.NewBasicLit(pos, p.basicLit(expr))
+               n := ir.NewBasicLit(p.pos(expr), p.basicLit(expr))
                if expr.Kind == syntax.RuneLit {
                        n.SetType(types.UntypedRune)
                }
@@ -1039,9 +1035,15 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) ir.Node {
        case *syntax.DeclStmt:
                return ir.NewBlockStmt(src.NoXPos, p.decls(stmt.DeclList))
        case *syntax.AssignStmt:
+               if stmt.Rhs == nil {
+                       pos := p.pos(stmt)
+                       n := ir.NewAssignOpStmt(pos, p.binOp(stmt.Op), p.expr(stmt.Lhs), ir.NewBasicLit(pos, one))
+                       n.IncDec = true
+                       return n
+               }
+
                if stmt.Op != 0 && stmt.Op != syntax.Def {
                        n := ir.NewAssignOpStmt(p.pos(stmt), p.binOp(stmt.Op), p.expr(stmt.Lhs), p.expr(stmt.Rhs))
-                       n.IncDec = stmt.Rhs == syntax.ImplicitOne
                        return n
                }
 
@@ -1502,7 +1504,7 @@ func (p *noder) wrapname(n syntax.Node, x ir.Node) ir.Node {
 }
 
 func (p *noder) setlineno(n syntax.Node) {
-       if n != nil && n != syntax.ImplicitOne {
+       if n != nil {
                base.Pos = p.pos(n)
        }
 }
index 7d79595a04eb1d4793acfd04473b31dec56cb195..267a34dbc83c34a221aa9d5a6db3297dabe98caa 100644 (file)
@@ -53,7 +53,7 @@ func (g *irgen) stmt0(stmt syntax.Stmt) ir.Node {
        case *syntax.AssignStmt:
                if stmt.Op != 0 && stmt.Op != syntax.Def {
                        op := g.op(stmt.Op, binOps[:])
-                       if stmt.Rhs == syntax.ImplicitOne {
+                       if stmt.Rhs == nil {
                                return IncDec(g.pos(stmt), op, g.expr(stmt.Lhs))
                        }
                        return ir.NewAssignOpStmt(g.pos(stmt), op, g.expr(stmt.Lhs), g.expr(stmt.Rhs))
index a06d6e85b1e82987bba07a557a7567794085c801..fb9786daa325c580d5402603e9241ae67ab36ddc 100644 (file)
@@ -367,7 +367,7 @@ type (
 
        AssignStmt struct {
                Op       Operator // 0 means no operation
-               Lhs, Rhs Expr     // Rhs == ImplicitOne means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
+               Lhs, Rhs Expr     // Rhs == nil means Lhs++ (Op == Add) or Lhs-- (Op == Sub)
                simpleStmt
        }
 
index e3fb1003a291c8347bcea8fe578505ca4aa1adeb..c4ccbb82cb55d521bdd70424e463fede623534fb 100644 (file)
@@ -1874,10 +1874,6 @@ func (p *parser) badExpr() *BadExpr {
 // ----------------------------------------------------------------------------
 // Statements
 
-// We represent x++, x-- as assignments x += ImplicitOne, x -= ImplicitOne.
-// ImplicitOne should not be used elsewhere.
-var ImplicitOne = &BasicLit{Value: "1"}
-
 // SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
 func (p *parser) simpleStmt(lhs Expr, keyword token) SimpleStmt {
        if trace {
@@ -1910,7 +1906,7 @@ func (p *parser) simpleStmt(lhs Expr, keyword token) SimpleStmt {
                        // lhs++ or lhs--
                        op := p.op
                        p.next()
-                       return p.newAssignStmt(pos, op, lhs, ImplicitOne)
+                       return p.newAssignStmt(pos, op, lhs, nil)
 
                case _Arrow:
                        // lhs <- rhs
index 161eb0d092d40551a377a5e59581afed1689bfdd..9109ce2363c38bdacc0aa562dcd470df1605e947 100644 (file)
@@ -549,7 +549,7 @@ func (p *printer) printRawNode(n Node) {
 
        case *AssignStmt:
                p.print(n.Lhs)
-               if n.Rhs == ImplicitOne {
+               if n.Rhs == nil {
                        // TODO(gri) This is going to break the mayCombine
                        //           check once we enable that again.
                        p.print(n.Op, n.Op) // ++ or --
index 418b26d674340542bc45f713f5749c7e895dffc1..c26e97a0d8f88771986be07a4a300ff98b993f4e 100644 (file)
@@ -207,7 +207,9 @@ func (w *walker) node(n Node) {
 
        case *AssignStmt:
                w.node(n.Lhs)
-               w.node(n.Rhs)
+               if n.Rhs != nil {
+                       w.node(n.Rhs)
+               }
 
        case *BranchStmt:
                if n.Label != nil {
index b728238d9f38c2755377989dc683cd0c0a9848b2..22dc47b1e76757f25106fbf3eb8520d9309a9313 100644 (file)
@@ -889,6 +889,7 @@ var binaryOpPredicates = opPredicates{
 }
 
 // The binary expression e may be nil. It's passed in for better error messages only.
+// TODO(gri) revisit use of e and opPos
 func (check *Checker) binary(x *operand, e *syntax.Operation, lhs, rhs syntax.Expr, op syntax.Operator, opPos syntax.Pos) {
        var y operand
 
index 0a19cd1a239a064e29e268bb9b72b12dcbce68e0..955bb2ad0802f9309b697e1d21b79877cf1d0041 100644 (file)
@@ -286,7 +286,7 @@ func endPos(n syntax.Node) syntax.Pos {
                        return n.Pos()
                case *syntax.AssignStmt:
                        m = n.Rhs
-                       if m == syntax.ImplicitOne {
+                       if m == nil {
                                p := endPos(n.Lhs)
                                return syntax.MakePos(p.Base(), p.Line(), p.Col()+2)
                        }
index 52b9794c102f17f799d600cd87d7befa2b5c6f2b..cbfe97b03c5d33182ba85d71f32f09fb828a9aa8 100644 (file)
@@ -367,47 +367,45 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
 
        case *syntax.AssignStmt:
                lhs := unpackExpr(s.Lhs)
-               rhs := unpackExpr(s.Rhs)
-               if s.Op == 0 || s.Op == syntax.Def {
-                       // regular assignment or short variable declaration
-                       if len(lhs) == 0 {
-                               check.invalidASTf(s, "missing lhs in assignment")
-                               return
-                       }
-                       if s.Op == syntax.Def {
-                               check.shortVarDecl(s.Pos(), lhs, rhs)
-                       } else {
-                               // regular assignment
-                               check.assignVars(lhs, rhs)
-                       }
-               } else {
-                       // assignment operations
-                       if len(lhs) != 1 || len(rhs) != 1 {
-                               check.errorf(s, "assignment operation %s requires single-valued expressions", s.Op)
+               if s.Rhs == nil {
+                       // x++ or x--
+                       if len(lhs) != 1 {
+                               check.invalidASTf(s, "%s%s requires one operand", s.Op, s.Op)
                                return
                        }
-
-                       // provide better error messages for x++ and x--
-                       if rhs[0] == syntax.ImplicitOne {
-                               var x operand
-                               check.expr(&x, lhs[0])
-                               if x.mode == invalid {
-                                       return
-                               }
-                               if !isNumeric(x.typ) {
-                                       check.invalidOpf(lhs[0], "%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
-                                       return
-                               }
-                       }
-
                        var x operand
-                       check.binary(&x, nil, lhs[0], rhs[0], s.Op, rhs[0].Pos()) // TODO(gri) should have TokPos here (like in go/types)
+                       check.expr(&x, lhs[0])
                        if x.mode == invalid {
                                return
                        }
+                       if !isNumeric(x.typ) {
+                               check.invalidOpf(lhs[0], "%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
+                               return
+                       }
                        check.assignVar(lhs[0], &x)
+                       return
+               }
+
+               rhs := unpackExpr(s.Rhs)
+               switch s.Op {
+               case 0:
+                       check.assignVars(lhs, rhs)
+                       return
+               case syntax.Def:
+                       check.shortVarDecl(s.Pos(), lhs, rhs)
+                       return
+               }
+
+               // assignment operations
+               if len(lhs) != 1 || len(rhs) != 1 {
+                       check.errorf(s, "assignment operation %s requires single-valued expressions", s.Op)
+                       return
                }
 
+               var x operand
+               check.binary(&x, nil, lhs[0], rhs[0], s.Op, s.Pos())
+               check.assignVar(lhs[0], &x)
+
        // case *syntax.GoStmt:
        //      check.suspendedCall("go", s.Call)