]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: quote user-supplied names in error messages
authorRobert Griesemer <gri@golang.org>
Wed, 13 Mar 2024 20:57:08 +0000 (13:57 -0700)
committerGopher Robot <gobot@golang.org>
Mon, 18 Mar 2024 18:59:40 +0000 (18:59 +0000)
Use `' quotes (as in `foo') to differentiate from Go quotes.
Quoting prevents confusion when user-supplied names alter
the meaning of the error message.

For instance, report

        duplicate method `wanted'

rather than

        duplicate method wanted

Exceptions:
- don't quote _:
        `_' is ugly and not necessary
- don't quote after a ":":
        undefined name: foo
- don't quote if the name is used correctly in a statement:
        goto L jumps over variable declaration

Quoting is done with a helper function and can be centrally adjusted
and fine-tuned as needed.

Adjusted some test cases to explicitly include the quoted names.

Fixes #65790.

Change-Id: Icce667215f303ab8685d3e5cb00d540a2fd372ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/571396
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>

33 files changed:
src/cmd/compile/internal/types2/builtins.go
src/cmd/compile/internal/types2/call.go
src/cmd/compile/internal/types2/check.go
src/cmd/compile/internal/types2/decl.go
src/cmd/compile/internal/types2/format.go
src/cmd/compile/internal/types2/issues_test.go
src/cmd/compile/internal/types2/labels.go
src/cmd/compile/internal/types2/stmt.go
src/cmd/compile/internal/types2/typeset.go
src/cmd/compile/internal/types2/typexpr.go
src/go/types/builtins.go
src/go/types/call.go
src/go/types/check.go
src/go/types/decl.go
src/go/types/format.go
src/go/types/issues_test.go
src/go/types/labels.go
src/go/types/stmt.go
src/go/types/typeset.go
src/go/types/typexpr.go
src/internal/types/testdata/check/builtins0.go
src/internal/types/testdata/check/decls0.go
src/internal/types/testdata/check/decls2/decls2a.go
src/internal/types/testdata/check/go1_13.go
src/internal/types/testdata/check/importdecl0/importdecl0a.go
src/internal/types/testdata/check/labels.go
src/internal/types/testdata/check/stmt0.go
src/internal/types/testdata/fixedbugs/issue50779.go
src/internal/types/testdata/fixedbugs/issue66285.go
test/fixedbugs/issue11361.go
test/fixedbugs/issue21317.go
test/fixedbugs/issue28268.go
test/fixedbugs/issue34329.go

index a87474ad6c1d31adadec4d95939287f53cb23ee7..b897a55212b917a3da9d8044dce44df36e2891c4 100644 (file)
@@ -25,7 +25,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        if hasDots(call) && id != _Append {
                check.errorf(dddErrPos(call),
                        InvalidDotDotDot,
-                       invalidOp+"invalid use of ... with built-in %s", bin.name)
+                       invalidOp+"invalid use of ... with built-in %s", quote(bin.name))
                check.use(argList...)
                return
        }
@@ -210,7 +210,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                                if id == _Len {
                                        code = InvalidLen
                                }
-                               check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
+                               check.errorf(x, code, invalidArg+"%s for %s", x, quote(bin.name))
                        }
                        return
                }
@@ -533,7 +533,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
        case _Max, _Min:
                // max(x, ...)
                // min(x, ...)
-               check.verifyVersionf(call.Fun, go1_21, bin.name)
+               check.verifyVersionf(call.Fun, go1_21, quote(bin.name))
 
                op := token.LSS
                if id == _Max {
@@ -576,7 +576,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                if x.mode != constant_ {
                        x.mode = value
                        // A value must not be untyped.
-                       check.assignment(x, &emptyInterface, "argument to "+bin.name)
+                       check.assignment(x, &emptyInterface, "argument to "+quote(bin.name))
                        if x.mode == invalid {
                                return
                        }
@@ -641,7 +641,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
                if nargs > 0 {
                        params = make([]Type, nargs)
                        for i, a := range args {
-                               check.assignment(a, nil, "argument to "+predeclaredFuncs[id].name)
+                               check.assignment(a, nil, "argument to "+quote(predeclaredFuncs[id].name))
                                if a.mode == invalid {
                                        return
                                }
@@ -992,7 +992,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
                default:
                        panic("unreachable")
                }
-               check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see go.dev/issue/50937)", x, predeclaredFuncs[id].name)
+               check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see go.dev/issue/50937)", x, quote(predeclaredFuncs[id].name))
 
                // Construct a suitable new type parameter for the result type.
                // The type parameter is placed in the current package so export/import
index 0a5de6667e18426efeec30b3cc12810a473afc5a..ca9772ff41df93669e29dac30086365c4bd248c1 100644 (file)
@@ -719,7 +719,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *TypeName
                                        goto Error
                                }
                                if !exp.Exported() {
-                                       check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
+                                       check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", quote(sel), quote(pkg.name))
                                        // ok to continue
                                }
                        }
index bf613fd28b277c18154b5a6da6ed31f21c1b49e2..2c6d77d6fdaeba3509c1d3801c3b266a800b3f73 100644 (file)
@@ -298,7 +298,7 @@ func (check *Checker) initFiles(files []*syntax.File) {
                        check.files = append(check.files, file)
 
                default:
-                       check.errorf(file, MismatchedPkgName, "package %s; expected %s", name, pkg.name)
+                       check.errorf(file, MismatchedPkgName, "package %s; expected %s", quote(name), quote(pkg.name))
                        // ignore this file
                }
        }
index c07a6b4deeee2873878e89d213d2f506fcb1bb60..ed7784a6b8635d2bdbf4dc64ba316be6e23ce1ea 100644 (file)
@@ -733,7 +733,7 @@ func (check *Checker) checkFieldUniqueness(base *Named) {
                                        // For historical consistency, we report the primary error on the
                                        // method, and the alt decl on the field.
                                        err := check.newError(DuplicateFieldAndMethod)
-                                       err.addf(alt, "field and method with the same name %s", fld.name)
+                                       err.addf(alt, "field and method with the same name %s", quote(fld.name))
                                        err.addAltDecl(fld)
                                        err.report()
                                }
index 442d219d1afa5793eaac77d745e9991495b0de34..1b9cf606b7771ce53bc42af2df945f863eb528c5 100644 (file)
@@ -14,6 +14,39 @@ import (
        "strings"
 )
 
+// quote encloses s in `' quotes, as in `foo', except for _,
+// which is left alone.
+//
+// Use to prevent confusion when user supplied names alter the
+// meaning of an error message.
+//
+// For instance, report
+//
+//     duplicate method `wanted'
+//
+// rather than
+//
+//     duplicate method wanted
+//
+// Exceptions:
+//
+//   - don't quote _:
+//     `_' is ugly and not necessary
+//   - don't quote after a ":" as there's no need for it:
+//     undefined name: foo
+//   - don't quote if the name is used correctly in a statement:
+//     goto L jumps over variable declaration
+//
+// quote encloses s in `' quotes, as in `foo',
+// except for _ which is left alone.
+func quote(s string) string {
+       if s == "_" {
+               // `_' is ugly and not necessary
+               return s
+       }
+       return "`" + s + "'"
+}
+
 func sprintf(qf Qualifier, tpSubscripts bool, format string, args ...any) string {
        for i, arg := range args {
                switch a := arg.(type) {
index 0275fe70d7148f8f882b8e6a3ed7301e72c65eab..8c9dfb32f541b21459dcc72de9ee1674b32ef2c9 100644 (file)
@@ -257,13 +257,12 @@ func TestIssue22525(t *testing.T) {
        got := "\n"
        conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
        typecheck(src, &conf, nil) // do not crash
-       want := `
-p:1:27: a declared and not used
-p:1:30: b declared and not used
-p:1:33: c declared and not used
-p:1:36: d declared and not used
-p:1:39: e declared and not used
-`
+       want := "\n" +
+               "p:1:27: `a' declared and not used\n" +
+               "p:1:30: `b' declared and not used\n" +
+               "p:1:33: `c' declared and not used\n" +
+               "p:1:36: `d' declared and not used\n" +
+               "p:1:39: `e' declared and not used\n"
        if got != want {
                t.Errorf("got: %swant: %s", got, want)
        }
index 8ea58ad0aa5bfbcff64986251447b53c9acd798c..61b3ca7511e9a1b4da7d45d4cfa8896af95ceff4 100644 (file)
@@ -28,9 +28,11 @@ func (check *Checker) labels(body *syntax.BlockStmt) {
                        msg = "goto %s jumps into block"
                        alt.(*Label).used = true // avoid another error
                        code = JumpIntoBlock
+                       // don't quote name here because "goto L" matches the code
                } else {
                        msg = "label %s not declared"
                        code = UndeclaredLabel
+                       name = quote(name)
                }
                check.errorf(jmp.Label, code, msg, name)
        }
@@ -39,7 +41,7 @@ func (check *Checker) labels(body *syntax.BlockStmt) {
        for name, obj := range all.elems {
                obj = resolve(name, obj)
                if lbl := obj.(*Label); !lbl.used {
-                       check.softErrorf(lbl.pos, UnusedLabel, "label %s declared and not used", lbl.name)
+                       check.softErrorf(lbl.pos, UnusedLabel, "label %s declared and not used", quote(lbl.name))
                }
        }
 }
@@ -135,7 +137,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
                                if alt := all.Insert(lbl); alt != nil {
                                        err := check.newError(DuplicateLabel)
                                        err.soft = true
-                                       err.addf(lbl.pos, "label %s already declared", name)
+                                       err.addf(lbl.pos, "label %s already declared", quote(name))
                                        err.addAltDecl(alt)
                                        err.report()
                                        // ok to continue
@@ -191,7 +193,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
                                        }
                                }
                                if !valid {
-                                       check.errorf(s.Label, MisplacedLabel, "invalid break label %s", name)
+                                       check.errorf(s.Label, MisplacedLabel, "invalid break label %s", quote(name))
                                        return
                                }
 
@@ -206,7 +208,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *syntax.Lab
                                        }
                                }
                                if !valid {
-                                       check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", name)
+                                       check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", quote(name))
                                        return
                                }
 
index 1a6ec4ffc1c88ab108edf7589a4caab1b59a62fd..7fd7009e132515c5bd182967b7c98c6e409f7912 100644 (file)
@@ -64,7 +64,7 @@ func (check *Checker) usage(scope *Scope) {
                return cmpPos(unused[i].pos, unused[j].pos) < 0
        })
        for _, v := range unused {
-               check.softErrorf(v.pos, UnusedVar, "%s declared and not used", v.name)
+               check.softErrorf(v.pos, UnusedVar, "%s declared and not used", quote(v.name))
        }
 
        for _, scope := range scope.children {
@@ -496,7 +496,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
                        for _, obj := range res.vars {
                                if alt := check.lookup(obj.name); alt != nil && alt != obj {
                                        err := check.newError(OutOfScopeResult)
-                                       err.addf(s, "result parameter %s not in scope at return", obj.name)
+                                       err.addf(s, "result parameter %s not in scope at return", quote(obj.name))
                                        err.addf(alt, "inner declaration of %s", obj)
                                        err.report()
                                        // ok to continue
index 63dafadeb43f6d63fc83708809ac145586c72ab9..2ce586e7a7eca62b99ac5b6fb47f09bd2571540f 100644 (file)
@@ -226,8 +226,8 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
                case explicit:
                        if check != nil {
                                err := check.newError(DuplicateDecl)
-                               err.addf(atPos(pos), "duplicate method %s", m.name)
-                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", m.name)
+                               err.addf(atPos(pos), "duplicate method %s", quote(m.name))
+                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", quote(m.name))
                                err.report()
                        }
                default:
@@ -240,8 +240,8 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_
                                check.later(func() {
                                        if pos.IsKnown() && !check.allowVersion(atPos(pos), go1_14) || !Identical(m.typ, other.Type()) {
                                                err := check.newError(DuplicateDecl)
-                                               err.addf(atPos(pos), "duplicate method %s", m.name)
-                                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", m.name)
+                                               err.addf(atPos(pos), "duplicate method %s", quote(m.name))
+                                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", quote(m.name))
                                                err.report()
                                        }
                                }).describef(atPos(pos), "duplicate method check for %s", m.name)
index be7c306a8d8ee5d7e47b5b2d413b4d7373192deb..c2037b26d62d6c918b078114ed08474f81170dc4 100644 (file)
@@ -87,7 +87,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType
 
        switch obj := obj.(type) {
        case *PkgName:
-               check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
+               check.errorf(e, InvalidPkgUse, "use of package %s not in selector", quote(obj.name))
                return
 
        case *Const:
@@ -109,7 +109,7 @@ func (check *Checker) ident(x *operand, e *syntax.Name, def *TypeName, wantType
 
        case *TypeName:
                if !check.enableAlias && check.isBrokenAlias(obj) {
-                       check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
+                       check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", quote(obj.name))
                        return
                }
                x.mode = typexpr
index 6519fa302ab34c33e775adeb27f06d411491d8ab..2272335945995ed57f3cbd6b5a051b431d92848c 100644 (file)
@@ -27,7 +27,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
        if hasDots(call) && id != _Append {
                check.errorf(dddErrPos(call),
                        InvalidDotDotDot,
-                       invalidOp+"invalid use of ... with built-in %s", bin.name)
+                       invalidOp+"invalid use of ... with built-in %s", quote(bin.name))
                check.use(argList...)
                return
        }
@@ -212,7 +212,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                                if id == _Len {
                                        code = InvalidLen
                                }
-                               check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
+                               check.errorf(x, code, invalidArg+"%s for %s", x, quote(bin.name))
                        }
                        return
                }
@@ -535,7 +535,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
        case _Max, _Min:
                // max(x, ...)
                // min(x, ...)
-               check.verifyVersionf(call.Fun, go1_21, bin.name)
+               check.verifyVersionf(call.Fun, go1_21, quote(bin.name))
 
                op := token.LSS
                if id == _Max {
@@ -578,7 +578,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                if x.mode != constant_ {
                        x.mode = value
                        // A value must not be untyped.
-                       check.assignment(x, &emptyInterface, "argument to "+bin.name)
+                       check.assignment(x, &emptyInterface, "argument to "+quote(bin.name))
                        if x.mode == invalid {
                                return
                        }
@@ -643,7 +643,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
                if nargs > 0 {
                        params = make([]Type, nargs)
                        for i, a := range args {
-                               check.assignment(a, nil, "argument to "+predeclaredFuncs[id].name)
+                               check.assignment(a, nil, "argument to "+quote(predeclaredFuncs[id].name))
                                if a.mode == invalid {
                                        return
                                }
@@ -994,7 +994,7 @@ func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId)
                default:
                        panic("unreachable")
                }
-               check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see go.dev/issue/50937)", x, predeclaredFuncs[id].name)
+               check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see go.dev/issue/50937)", x, quote(predeclaredFuncs[id].name))
 
                // Construct a suitable new type parameter for the result type.
                // The type parameter is placed in the current package so export/import
index b4f155a501169574ff9e87dd2e2ea7992fd2adc2..bee97a182b31acd5f5c0d9706e5bbb22849d4daa 100644 (file)
@@ -722,7 +722,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *TypeName, w
                                        goto Error
                                }
                                if !exp.Exported() {
-                                       check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
+                                       check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", quote(sel), quote(pkg.name))
                                        // ok to continue
                                }
                        }
index 6da42e63f67c2d95a8975d7369bcb4589ea1252e..763be7714f339a54369d717a640ca2448a505358 100644 (file)
@@ -303,7 +303,7 @@ func (check *Checker) initFiles(files []*ast.File) {
                        check.files = append(check.files, file)
 
                default:
-                       check.errorf(atPos(file.Package), MismatchedPkgName, "package %s; expected %s", name, pkg.name)
+                       check.errorf(atPos(file.Package), MismatchedPkgName, "package %s; expected %s", quote(name), quote(pkg.name))
                        // ignore this file
                }
        }
index 19472382af37221fec8998c561e0b8682229d28e..7de27eeb56af05187356219ecede30d241e45d27 100644 (file)
@@ -825,7 +825,7 @@ func (check *Checker) checkFieldUniqueness(base *Named) {
                                        // For historical consistency, we report the primary error on the
                                        // method, and the alt decl on the field.
                                        err := check.newError(DuplicateFieldAndMethod)
-                                       err.addf(alt, "field and method with the same name %s", fld.name)
+                                       err.addf(alt, "field and method with the same name %s", quote(fld.name))
                                        err.addAltDecl(fld)
                                        err.report()
                                }
index 09e599c3c336afaacae72b5ee725a603b7a06ffa..f5edb0144978aebc8186783feb29013bc63d8472 100644 (file)
@@ -15,6 +15,39 @@ import (
        "strings"
 )
 
+// quote encloses s in `' quotes, as in `foo', except for _,
+// which is left alone.
+//
+// Use to prevent confusion when user supplied names alter the
+// meaning of an error message.
+//
+// For instance, report
+//
+//     duplicate method `wanted'
+//
+// rather than
+//
+//     duplicate method wanted
+//
+// Exceptions:
+//
+//   - don't quote _:
+//     `_' is ugly and not necessary
+//   - don't quote after a ":" as there's no need for it:
+//     undefined name: foo
+//   - don't quote if the name is used correctly in a statement:
+//     goto L jumps over variable declaration
+//
+// quote encloses s in `' quotes, as in `foo',
+// except for _ which is left alone.
+func quote(s string) string {
+       if s == "_" {
+               // `_' is ugly and not necessary
+               return s
+       }
+       return "`" + s + "'"
+}
+
 func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
        for i, arg := range args {
                switch a := arg.(type) {
index 6f9d5978e7ff22ee5d47ed87abbef7b0d6f6e53f..4f4bf6f07704135fa19f4f6c4ba11911cdd65f0a 100644 (file)
@@ -265,13 +265,12 @@ func TestIssue22525(t *testing.T) {
        got := "\n"
        conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
        typecheck(src, &conf, nil) // do not crash
-       want := `
-p:1:27: a declared and not used
-p:1:30: b declared and not used
-p:1:33: c declared and not used
-p:1:36: d declared and not used
-p:1:39: e declared and not used
-`
+       want := "\n" +
+               "p:1:27: `a' declared and not used\n" +
+               "p:1:30: `b' declared and not used\n" +
+               "p:1:33: `c' declared and not used\n" +
+               "p:1:36: `d' declared and not used\n" +
+               "p:1:39: `e' declared and not used\n"
        if got != want {
                t.Errorf("got: %swant: %s", got, want)
        }
index 04e84083b51f4bab649d2e4d45926dddfd598cd0..c3fd437c14d12646d609191a3684ad434301c05e 100644 (file)
@@ -29,9 +29,11 @@ func (check *Checker) labels(body *ast.BlockStmt) {
                        msg = "goto %s jumps into block"
                        alt.(*Label).used = true // avoid another error
                        code = JumpIntoBlock
+                       // don't quote name here because "goto L" matches the code
                } else {
                        msg = "label %s not declared"
                        code = UndeclaredLabel
+                       name = quote(name)
                }
                check.errorf(jmp.Label, code, msg, name)
        }
@@ -40,7 +42,7 @@ func (check *Checker) labels(body *ast.BlockStmt) {
        for name, obj := range all.elems {
                obj = resolve(name, obj)
                if lbl := obj.(*Label); !lbl.used {
-                       check.softErrorf(lbl, UnusedLabel, "label %s declared and not used", lbl.name)
+                       check.softErrorf(lbl, UnusedLabel, "label %s declared and not used", quote(lbl.name))
                }
        }
 }
@@ -140,7 +142,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele
                                if alt := all.Insert(lbl); alt != nil {
                                        err := check.newError(DuplicateLabel)
                                        err.soft = true
-                                       err.addf(lbl, "label %s already declared", name)
+                                       err.addf(lbl, "label %s already declared", quote(name))
                                        err.addAltDecl(alt)
                                        err.report()
                                        // ok to continue
@@ -196,7 +198,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele
                                        }
                                }
                                if !valid {
-                                       check.errorf(s.Label, MisplacedLabel, "invalid break label %s", name)
+                                       check.errorf(s.Label, MisplacedLabel, "invalid break label %s", quote(name))
                                        return
                                }
 
@@ -211,7 +213,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele
                                        }
                                }
                                if !valid {
-                                       check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", name)
+                                       check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", quote(name))
                                        return
                                }
 
index 4fd37a68f019fa2f2ea87097a208d0120fcce160..30b49482160b276c338d5cfb76b27cdb06a10927 100644 (file)
@@ -65,7 +65,7 @@ func (check *Checker) usage(scope *Scope) {
                return cmpPos(unused[i].pos, unused[j].pos) < 0
        })
        for _, v := range unused {
-               check.softErrorf(v, UnusedVar, "%s declared and not used", v.name)
+               check.softErrorf(v, UnusedVar, "%s declared and not used", quote(v.name))
        }
 
        for _, scope := range scope.children {
@@ -515,7 +515,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
                        for _, obj := range res.vars {
                                if alt := check.lookup(obj.name); alt != nil && alt != obj {
                                        err := check.newError(OutOfScopeResult)
-                                       err.addf(s, "result parameter %s not in scope at return", obj.name)
+                                       err.addf(s, "result parameter %s not in scope at return", quote(obj.name))
                                        err.addf(alt, "inner declaration of %s", obj)
                                        err.report()
                                        // ok to continue
index 2e2ebb30f77772589c253a1ff33bc28c760167b3..84eb83fb5f809957600568d195a3b1c373375369 100644 (file)
@@ -228,8 +228,8 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
                case explicit:
                        if check != nil {
                                err := check.newError(DuplicateDecl)
-                               err.addf(atPos(pos), "duplicate method %s", m.name)
-                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", m.name)
+                               err.addf(atPos(pos), "duplicate method %s", quote(m.name))
+                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", quote(m.name))
                                err.report()
                        }
                default:
@@ -242,8 +242,8 @@ func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_T
                                check.later(func() {
                                        if pos.IsValid() && !check.allowVersion(atPos(pos), go1_14) || !Identical(m.typ, other.Type()) {
                                                err := check.newError(DuplicateDecl)
-                                               err.addf(atPos(pos), "duplicate method %s", m.name)
-                                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", m.name)
+                                               err.addf(atPos(pos), "duplicate method %s", quote(m.name))
+                                               err.addf(atPos(mpos[other.(*Func)]), "other declaration of %s", quote(m.name))
                                                err.report()
                                        }
                                }).describef(atPos(pos), "duplicate method check for %s", m.name)
index 7179a2466c60a9f428dc69d0b34b446bf41984ca..79e4c0ab661882afbc5e2a6a110d8ad883dcf0c6 100644 (file)
@@ -88,7 +88,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bo
 
        switch obj := obj.(type) {
        case *PkgName:
-               check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
+               check.errorf(e, InvalidPkgUse, "use of package %s not in selector", quote(obj.name))
                return
 
        case *Const:
@@ -110,7 +110,7 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *TypeName, wantType bo
 
        case *TypeName:
                if !check.enableAlias && check.isBrokenAlias(obj) {
-                       check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
+                       check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", quote(obj.name))
                        return
                }
                x.mode = typexpr
index 12d8fbfd0e41e6bb0f748f63f8127cba5f3295e3..2bfece824eaa46f267eb62b998ca8d477a24b5b0 100644 (file)
@@ -100,7 +100,10 @@ func cap1() {
 
        var s [][]byte
        _ = cap(s)
-       _ = cap(s... /* ERROR "invalid use of ..." */ )
+       _ = cap(s... /* ERROR "invalid use of ... with built-in `cap'" */ )
+
+       var x int
+       _ = cap(x /* ERROR "invalid argument: x (variable of type int) for `cap'" */ )
 }
 
 func cap2() {
index 0b99faab19289a1aa7483f3f692b5343922949cd..bec2b17ada9c8b1d6718025d176b656a013bb49b 100644 (file)
@@ -137,7 +137,7 @@ type (
        }
        I3 interface {
                m1()
-               m1 /* ERROR "duplicate method" */ ()
+               m1 /* ERROR "duplicate method `m1'" */ ()
        }
        I4 interface {
                m1(x, y, x /* ERROR "redeclared" */ float32)
index c2fb421b9611d7fc050db02b38526df64fa99fad..f14b709dcf21fc93ff319879aa1049e25b7cf9ad 100644 (file)
@@ -16,7 +16,7 @@ type T1 struct{
 
 func (T1) m() {}
 func (T1) m /* ERROR "already declared" */ () {}
-func (x *T1) f /* ERROR "field and method" */ () {}
+func (x *T1) f /* ERROR "field and method with the same name `f'" */ () {}
 
 // Conflict between embedded field and method name,
 // with the embedded field being a basic type.
@@ -30,7 +30,7 @@ type T1c struct {
        time.Time
 }
 
-func (T1c) Time /* ERROR "field and method" */ () int { return 0 }
+func (T1c) Time /* ERROR "field and method with the same name `Time'" */ () int { return 0 }
 
 // Disabled for now: LookupFieldOrMethod will find Pointer even though
 // it's double-declared (it would cost extra in the common case to verify
index cc7861d616100222ffddabec24b6cc75d2e4dadc..3340124cfaa3d5d366951205890e3a85da7bb980 100644 (file)
@@ -14,10 +14,10 @@ type I interface { m() }
 
 type _ interface {
        m()
-       I // ERROR "duplicate method m"
+       I // ERROR "duplicate method `m'"
 }
 
 type _ interface {
        I
-       I // ERROR "duplicate method m"
+       I // ERROR "duplicate method `m'"
 }
index d514ae4cb70fd23396c6a2dbfaab058aa57269f6..b255c193753ed5e6cf62d7a1dde7e2de3ae88a91 100644 (file)
@@ -32,7 +32,7 @@ import f2 "fmt"
 
 // reflect.flag must not be visible in this package
 type flag int
-type _ reflect.flag /* ERROR "not exported" */
+type _ reflect.flag /* ERROR "`flag' not exported by package `reflect'" */
 
 // imported package name may conflict with local objects
 type reflect /* ERROR "reflect already declared" */ int
index 5948952fbe53398ab0806c15eaeef83814d86323..0a59e9e2dc9462f493353c6573f1fbe94b6e47b7 100644 (file)
@@ -10,23 +10,23 @@ package labels
 var x int
 
 func f0() {
-L1 /* ERROR "label L1 declared and not used" */ :
+L1 /* ERROR "label `L1' declared and not used" */ :
        for {
        }
-L2 /* ERROR "label L2 declared and not used" */ :
+L2 /* ERROR "label `L2' declared and not used" */ :
        select {
        }
-L3 /* ERROR "label L3 declared and not used" */ :
+L3 /* ERROR "label `L3' declared and not used" */ :
        switch {
        }
-L4 /* ERROR "label L4 declared and not used" */ :
+L4 /* ERROR "label `L4' declared and not used" */ :
        if true {
        }
-L5 /* ERROR "label L5 declared and not used" */ :
+L5 /* ERROR "label `L5' declared and not used" */ :
        f0()
 L6:
        f0()
-L6 /* ERROR "label L6 already declared" */ :
+L6 /* ERROR "label `L6' already declared" */ :
        f0()
        if x == 20 {
                goto L6
@@ -35,7 +35,7 @@ L6 /* ERROR "label L6 already declared" */ :
 L7:
        for {
                break L7
-               break L8 /* ERROR "invalid break label L8" */
+               break L8 /* ERROR "invalid break label `L8'" */
        }
 
 // A label must be directly associated with a switch, select, or
@@ -43,8 +43,8 @@ L7:
 
 L7a /* ERROR "declared and not used" */ : L7b:
        for {
-               break L7a /* ERROR "invalid break label L7a" */
-               continue L7a /* ERROR "invalid continue label L7a" */
+               break L7a /* ERROR "invalid break label `L7a'" */
+               continue L7a /* ERROR "invalid continue label `L7a'" */
                continue L7b
        }
 
@@ -52,7 +52,7 @@ L8:
        for {
                if x == 21 {
                        continue L8
-                       continue L7 /* ERROR "invalid continue label L7" */
+                       continue L7 /* ERROR "invalid continue label `L7'" */
                }
        }
 
@@ -60,23 +60,23 @@ L9:
        switch {
        case true:
                break L9
-       defalt /* ERROR "label defalt declared and not used" */ :
+       defalt /* ERROR "label `defalt' declared and not used" */ :
        }
 
 L10:
        select {
        default:
                break L10
-               break L9 /* ERROR "invalid break label L9" */
+               break L9 /* ERROR "invalid break label `L9'" */
        }
 
        goto L10a
 L10a: L10b:
        select {
        default:
-               break L10a /* ERROR "invalid break label L10a" */
+               break L10a /* ERROR "invalid break label `L10a'" */
                break L10b
-               continue L10b /* ERROR "invalid continue label L10b" */
+               continue L10b /* ERROR "invalid continue label `L10b'" */
        }
 }
 
@@ -99,7 +99,7 @@ L2:
                        break L2
                }
                if x == 1 {
-                       continue L2 /* ERROR "invalid continue label L2" */
+                       continue L2 /* ERROR "invalid continue label `L2'" */
                }
                goto L2
        }
@@ -111,7 +111,7 @@ L3:
                        break L3
                }
                if x == 12 {
-                       continue L3 /* ERROR "invalid continue label L3" */
+                       continue L3 /* ERROR "invalid continue label `L3'" */
                }
                goto L3
        }
@@ -119,10 +119,10 @@ L3:
 L4:
        if true {
                if x == 13 {
-                       break L4 /* ERROR "invalid break label L4" */
+                       break L4 /* ERROR "invalid break label `L4'" */
                }
                if x == 14 {
-                       continue L4 /* ERROR "invalid continue label L4" */
+                       continue L4 /* ERROR "invalid continue label `L4'" */
                }
                if x == 15 {
                        goto L4
@@ -132,10 +132,10 @@ L4:
 L5:
        f1()
        if x == 16 {
-               break L5 /* ERROR "invalid break label L5" */
+               break L5 /* ERROR "invalid break label `L5'" */
        }
        if x == 17 {
-               continue L5 /* ERROR "invalid continue label L5" */
+               continue L5 /* ERROR "invalid continue label `L5'" */
        }
        if x == 18 {
                goto L5
@@ -143,10 +143,10 @@ L5:
 
        for {
                if x == 19 {
-                       break L1 /* ERROR "invalid break label L1" */
+                       break L1 /* ERROR "invalid break label `L1'" */
                }
                if x == 20 {
-                       continue L1 /* ERROR "invalid continue label L1" */
+                       continue L1 /* ERROR "invalid continue label `L1'" */
                }
                if x == 21 {
                        goto L1
@@ -157,10 +157,10 @@ L5:
 // Additional tests not in the original files.
 
 func f2() {
-L1 /* ERROR "label L1 declared and not used" */ :
+L1 /* ERROR "label `L1' declared and not used" */ :
        if x == 0 {
                for {
-                       continue L1 /* ERROR "invalid continue label L1" */
+                       continue L1 /* ERROR "invalid continue label `L1'" */
                }
        }
 }
@@ -170,11 +170,11 @@ L1:
 L2:
 L3:
        for {
-               break L1 /* ERROR "invalid break label L1" */
-               break L2 /* ERROR "invalid break label L2" */
+               break L1 /* ERROR "invalid break label `L1'" */
+               break L2 /* ERROR "invalid break label `L2'" */
                break L3
-               continue L1 /* ERROR "invalid continue label L1" */
-               continue L2 /* ERROR "invalid continue label L2" */
+               continue L1 /* ERROR "invalid continue label `L1'" */
+               continue L2 /* ERROR "invalid continue label `L2'" */
                continue L3
                goto L1
                goto L2
index b61f1c72320f79cf22388a078ca85f3747378c8b..a6c47cb48301a2ad8535ebbafafb22f8359c6c8f 100644 (file)
@@ -222,7 +222,7 @@ func selects() {
        ch2 := make(chan int)
        select {
        case <-ch1:
-               var ch2 /* ERROR "ch2 declared and not used" */ chan bool
+               var ch2 /* ERROR "`ch2' declared and not used" */ chan bool
        case i := <-ch2:
                print(i + 1)
        }
@@ -394,7 +394,7 @@ func returns2() (a, b int) {
        {
                type a int
                return 1, 2
-               return /* ERROR "a not in scope at return" */
+               return /* ERROR "`a' not in scope at return" */
        }
 }
 
index 59c0f2d6a015750eb73237450dcf459c06374c27..a0a126dff017c8536d4ae269bfee35f09532428e 100644 (file)
@@ -17,7 +17,7 @@ type R[S any, P any] struct{}
 type SR = R[SS, ST]
 
 type SS interface {
-       NSR(any) *SR // ERROR "invalid use of type alias SR in recursive type"
+       NSR(any) *SR // ERROR "invalid use of type alias `SR' in recursive type"
 }
 
 type C interface {
index 9811fec3f35549aaeb0ce670de453b0d1b1ad8fc..2e8bb59508f4d51a897eecc9bc71c9e793304f7c 100644 (file)
@@ -19,7 +19,7 @@ import "io"
 
 type _ interface {
        Reader
-       Reader // ERROR "duplicate method Read"
+       Reader // ERROR "duplicate method `Read'"
 }
 
 type Reader interface {
@@ -28,10 +28,10 @@ type Reader interface {
 
 type _ interface {
        io.Reader
-       Reader // ERROR "duplicate method Read"
+       Reader // ERROR "duplicate method `Read'"
 }
 
 type _ interface {
        io.Reader
-       io /* ERROR "duplicate method Read" */ .Reader
+       io /* ERROR "duplicate method `Read'" */ .Reader
 }
index 1ef8735a525a40366b4f22809a3f3fe9ac2fe895..84e71c73e60991b8f1a73813ef8256de6772a158 100644 (file)
@@ -8,4 +8,4 @@ package a
 
 import "fmt"  // GC_ERROR "imported and not used"
 
-const n = fmt // ERROR "fmt without selector|unexpected reference to package|use of package fmt not in selector"
+const n = fmt // ERROR "fmt without selector|unexpected reference to package|use of package `fmt' not in selector"
index cebfc0f52d67935f8d6228fca818804ccefd79bd..d525f12a58af1a5194452b8863da80e107a03045 100644 (file)
@@ -45,8 +45,8 @@ func main() {
                log.Fatalf("expected cmd/compile to fail")
        }
        wantErrs := []string{
-               "7:9: n declared and not used",
-               "7:12: err declared and not used",
+               "7:9: `n' declared and not used",
+               "7:12: `err' declared and not used",
        }
        outStr := string(out)
        for _, want := range wantErrs {
index 263b2d1b425b7df9d3476350d81fbe5a3da9df12..b04e42555fecb41ecca6c0775c17447559b3c677 100644 (file)
@@ -16,8 +16,8 @@ type T struct {
 
 type E struct{}
 
-func (T) b()  {} // ERROR "field and method named b|redeclares struct field name|field and method with the same name b"
-func (*T) E() {} // ERROR "field and method named E|redeclares struct field name|field and method with the same name E"
+func (T) b()  {} // ERROR "field and method named b|redeclares struct field name|field and method with the same name `b'"
+func (*T) E() {} // ERROR "field and method named E|redeclares struct field name|field and method with the same name `E'"
 
 func _() {
        var x T
index 790686e3ddfbd81a905a7df2644191984a9460f1..585770d87a4d8d8ceda722dc8318aab740f0dd33 100644 (file)
@@ -10,5 +10,5 @@ type I interface { M() }
 
 type _ interface {
        I
-       I // ERROR "duplicate method M"
+       I // ERROR "duplicate method `M'"
 }