]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: improved error message when calling a shadowed builtin
authorDaniel Martí <mvdan@mvdan.cc>
Tue, 27 Feb 2018 18:54:50 +0000 (18:54 +0000)
committerDaniel Martí <mvdan@mvdan.cc>
Wed, 28 Feb 2018 19:39:52 +0000 (19:39 +0000)
Otherwise, the error can be confusing if one forgets or doesn't know
that the builtin is being shadowed, which is not common practice.

Fixes #22822.

Change-Id: I735393b5ce28cb83815a1c3f7cd2e7bb5080a32d
Reviewed-on: https://go-review.googlesource.com/97455
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/universe.go
test/fixedbugs/issue22822.go [new file with mode: 0644]

index 75ecaa3d4159226c262e1cd887ff688e50a0f2d1..562c37f24d69506b0084f86a43514bf16f5c73b0 100644 (file)
@@ -1250,7 +1250,15 @@ func typecheck1(n *Node, top int) *Node {
                default:
                        n.Op = OCALLFUNC
                        if t.Etype != TFUNC {
-                               yyerror("cannot call non-function %v (type %v)", l, t)
+                               name := l.String()
+                               if isBuiltinFuncName(name) {
+                                       // be more specific when the function
+                                       // name matches a predeclared function
+                                       yyerror("cannot call non-function %s (type %v), declared at %s",
+                                               name, t, linestr(l.Name.Defn.Pos))
+                               } else {
+                                       yyerror("cannot call non-function %s (type %v)", name, t)
+                               }
                                n.Type = nil
                                return n
                        }
index ea901db744fcd3a19990e2df1e954bfd098bc478..a255ae08c0f92dd9045863a6097f41dd5631b2e3 100644 (file)
@@ -65,6 +65,17 @@ var builtinFuncs = [...]struct {
        {"recover", ORECOVER},
 }
 
+// isBuiltinFuncName reports whether name matches a builtin function
+// name.
+func isBuiltinFuncName(name string) bool {
+       for _, fn := range builtinFuncs {
+               if fn.name == name {
+                       return true
+               }
+       }
+       return false
+}
+
 var unsafeFuncs = [...]struct {
        name string
        op   Op
diff --git a/test/fixedbugs/issue22822.go b/test/fixedbugs/issue22822.go
new file mode 100644 (file)
index 0000000..e449ddb
--- /dev/null
@@ -0,0 +1,16 @@
+// errorcheck
+
+// Copyright 2018 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.
+
+// Check that calling a function shadowing a built-in provides a good
+// error message.
+
+package main
+
+func F() {
+       slice := []int{1, 2, 3}
+       len := int(2)
+       println(len(slice)) // ERROR "cannot call non-function len .type int., declared at"
+}