cmd/compile/internal/syntax: better error msg for some 'if' statements

R=go1.11

A common error is to write '=' instead of '==' inside the condition
of a simple 'if' statement:

	if x = 0 { ... }

Highlight the fact that we have an assignment in the error message
to prevent further confusion.

Fixes #23385.

Change-Id: I1552050fd6da927bd12a1be0977bd2e98eca5885
Reviewed-on: https://go-review.googlesource.com/87316
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 6b52950..d01ad60 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -170,9 +170,9 @@
 	switch {
 	case msg == "":
 		// nothing to do
-	case strings.HasPrefix(msg, "in"), strings.HasPrefix(msg, "at"), strings.HasPrefix(msg, "after"):
+	case strings.HasPrefix(msg, "in "), strings.HasPrefix(msg, "at "), strings.HasPrefix(msg, "after "):
 		msg = " " + msg
-	case strings.HasPrefix(msg, "expecting"):
+	case strings.HasPrefix(msg, "expecting "):
 		msg = ", " + msg
 	default:
 		// plain error - we don't care about current token
@@ -1844,7 +1844,15 @@
 	case *ExprStmt:
 		cond = s.X
 	default:
-		p.syntax_error(fmt.Sprintf("%s used as value", String(s)))
+		// A common syntax error is to write '=' instead of '==',
+		// which turns an expression into an assignment. Provide
+		// a more explicit error message in that case to prevent
+		// further confusion.
+		str := String(s)
+		if as, ok := s.(*AssignStmt); ok && as.Op == 0 {
+			str = "assignment " + str
+		}
+		p.syntax_error(fmt.Sprintf("%s used as value", str))
 	}
 
 	p.xnest = outer