Skip to content

Commit

Permalink
cmd/compile/internal/syntax: better error when an assignment is used …
Browse files Browse the repository at this point in the history
…in value context

The error message is now positioned at the statement position (which is
an identifing token, such as the '=' for assignments); and in case of
assignments it emphasizes the assignment by putting the Lhs and Rhs
in parentheses. Finally, the wording is changed from "use of * as value"
to the stronger "cannot use * as value" (for which there is precedent
elsewhere in the parser).

Fixes #36858.

Change-Id: Ic3f101bba50f58e3a1d9b29645066634631f2d61
Reviewed-on: https://go-review.googlesource.com/c/go/+/218337
Reviewed-by: Matthew Dempsky <[email protected]>
  • Loading branch information
griesemer committed Feb 21, 2020
1 parent d532d5f commit ffc0573
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 10 deletions.
11 changes: 8 additions & 3 deletions src/cmd/compile/internal/syntax/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1886,11 +1886,16 @@ done:
// which turns an expression into an assignment. Provide
// a more explicit error message in that case to prevent
// further confusion.
str := String(s)
var str string
if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
str = "assignment " + str
// 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) + ")"
} else {
str = String(s)
}
p.syntaxError(fmt.Sprintf("%s used as value", str))
p.syntaxErrorAt(s.Pos(), fmt.Sprintf("cannot use %s as value", str))
}

p.xnest = outer
Expand Down
9 changes: 7 additions & 2 deletions src/cmd/compile/internal/syntax/testdata/issue23385.src
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

package p

func f() {
if true || 0 = 1 /* ERROR assignment .* used as value */ {
func _() {
if true || 0 /* ERROR cannot use assignment .* as value */ = 1 {
}
}

func _(a, b string) {
if a == "a" && b /* ERROR cannot use assignment .* as value */ = "b" {
}
}
6 changes: 3 additions & 3 deletions test/fixedbugs/issue18915.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
package p

func _() {
if a := 10 { // ERROR "a := 10 used as value"
if a := 10 { // ERROR "cannot use a := 10 as value"
}

for b := 10 { // ERROR "b := 10 used as value"
for b := 10 { // ERROR "cannot use b := 10 as value"
}

switch c := 10 { // ERROR "c := 10 used as value"
switch c := 10 { // ERROR "cannot use c := 10 as value"
}
}
2 changes: 1 addition & 1 deletion test/syntax/chan1.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var c chan int
var v int

func main() {
if c <- v { // ERROR "used as value"
if c <- v { // ERROR "cannot use c <- v as value"
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/syntax/typesw.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package main

func main() {
switch main() := interface{}(nil).(type) { // ERROR "invalid variable name|used as value"
switch main() := interface{}(nil).(type) { // ERROR "invalid variable name|cannot use .* as value"
default:
}
}

0 comments on commit ffc0573

Please sign in to comment.