]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/syntax: better error message when using = instead of ==
authorRobert Griesemer <gri@golang.org>
Mon, 5 Jun 2023 16:30:58 +0000 (09:30 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 6 Jun 2023 14:42:44 +0000 (14:42 +0000)
When = is used instead of == as part of a conditional expression,
the parser message emphasizes the LHS and RHS of = by always
parenthesizing the two sides. For example, for:

if x = y {}

the error is:

        cannot use assignment (x) = (y) as value

This is done to highlight the LHS and RHS in case of more complex
cases such as

        if x || y = z {}

which one may incorrectly read as (x) || (y == z) rather than the
correct (x || y) = z.

This CL fine-tunes the error message a bit by only adding the
parentheses if the LHS and RHS are binary expressions.

Fixes #60599.
For #23385.

Change-Id: Ida4c8d12464cc2ac15c934f24858eb6f43cf9950
Reviewed-on: https://go-review.googlesource.com/c/go/+/500975
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/testdata/issue60599.go [new file with mode: 0644]

index c8b8ab06018b8eea07c4c39eb689cc3164241bc8..b5602fcff7cda6e86c71897f12f8e95af902621b 100644 (file)
@@ -2369,10 +2369,8 @@ done:
                // further confusion.
                var str string
                if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
-                       // Emphasize Lhs and Rhs of assignment with parentheses to highlight '='.
-                       // Do it always - it's not worth going through the trouble of doing it
-                       // only for "complex" left and right sides.
-                       str = "assignment (" + String(as.Lhs) + ") = (" + String(as.Rhs) + ")"
+                       // Emphasize complex Lhs and Rhs of assignment with parentheses to highlight '='.
+                       str = "assignment " + emphasize(as.Lhs) + " = " + emphasize(as.Rhs)
                } else {
                        str = String(s)
                }
@@ -2383,6 +2381,17 @@ done:
        return
 }
 
+// emphasize returns a string representation of x, with (top-level)
+// binary expressions emphasized by enclosing them in parentheses.
+func emphasize(x Expr) string {
+       s := String(x)
+       if op, _ := x.(*Operation); op != nil && op.Y != nil {
+               // binary expression
+               return "(" + s + ")"
+       }
+       return s
+}
+
 func (p *parser) ifStmt() *IfStmt {
        if trace {
                defer p.trace("ifStmt")()
diff --git a/src/cmd/compile/internal/syntax/testdata/issue60599.go b/src/cmd/compile/internal/syntax/testdata/issue60599.go
new file mode 100644 (file)
index 0000000..711d97b
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _(x, y, z int) {
+       if x /* ERROR cannot use assignment x = y as value */ = y {}
+       if x || y /* ERROR cannot use assignment \(x || y\) = z as value */ = z {}
+       if x /* ERROR cannot use assignment x = \(y || z\) as value */ = y || z {}
+}