2 // Copyright 2012 The Go Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
6 // This file implements various error reporters.
12 "cmd/compile/internal/syntax"
18 func unimplemented() {
19 panic("unimplemented")
24 panic("assertion failed")
32 func (check *Checker) qualifier(pkg *Package) string {
33 // Qualify the package unless it's the package being type-checked.
35 // If the same package name was used by multiple packages, display the full path.
36 if check.pkgCnt[pkg.name] > 1 {
37 return strconv.Quote(pkg.path)
44 func (check *Checker) sprintf(format string, args ...interface{}) string {
45 for i, arg := range args {
46 switch a := arg.(type) {
50 panic("internal error: should always pass *operand")
52 arg = operandString(a, check.qualifier)
56 arg = syntax.String(a)
58 arg = ObjectString(a, check.qualifier)
60 arg = TypeString(a, check.qualifier)
64 return fmt.Sprintf(format, args...)
67 func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
68 fmt.Printf("%s:\t%s%s\n",
70 strings.Repeat(". ", check.indent),
71 check.sprintf(format, args...),
75 // dump is only needed for debugging
76 func (check *Checker) dump(format string, args ...interface{}) {
77 fmt.Println(check.sprintf(format, args...))
80 func (check *Checker) err(pos syntax.Pos, msg string, soft bool) {
81 // Cheap trick: Don't report errors with messages containing
82 // "invalid operand" or "invalid type" as those tend to be
83 // follow-on errors which don't add useful information. Only
84 // exclude them if these strings are not at the beginning,
85 // and only if we have at least one error already reported.
86 if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) {
90 // If we are encountering an error while evaluating an inherited
91 // constant initialization expression, pos is the position of in
92 // the original expression, and not of the currently declared
93 // constant identifier. Use the provided errpos instead.
94 // TODO(gri) We may also want to augment the error message and
95 // refer to the position (pos) in the original expression.
96 if check.errpos.IsKnown() {
97 assert(check.iota != nil)
101 err := Error{pos, stripAnnotations(msg), msg, soft}
102 if check.firstErr == nil {
106 if check.conf.Trace {
107 check.trace(pos, "ERROR: %s", msg)
110 f := check.conf.Error
112 panic(bailout{}) // report only first error
117 type poser interface {
121 func (check *Checker) error(at poser, msg string) {
122 check.err(posFor(at), msg, false)
125 func (check *Checker) errorf(at poser, format string, args ...interface{}) {
126 check.err(posFor(at), check.sprintf(format, args...), false)
129 func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
130 check.err(posFor(at), check.sprintf(format, args...), true)
133 func (check *Checker) invalidASTf(at poser, format string, args ...interface{}) {
134 check.errorf(at, "invalid AST: "+format, args...)
137 func (check *Checker) invalidArgf(at poser, format string, args ...interface{}) {
138 check.errorf(at, "invalid argument: "+format, args...)
141 func (check *Checker) invalidOpf(at poser, format string, args ...interface{}) {
142 check.errorf(at, "invalid operation: "+format, args...)
145 // posFor reports the left (= start) position of at.
146 func posFor(at poser) syntax.Pos {
147 switch x := at.(type) {
150 return startPos(x.expr)
158 // stripAnnotations removes internal (type) annotations from s.
159 func stripAnnotations(s string) string {
160 // Would like to use strings.Builder but it's not available in Go 1.4.
162 for _, r := range s {
163 // strip #'s and subscript digits
164 if r != instanceMarker && !('₀' <= r && r < '₀'+10) { // '₀' == U+2080
168 if b.Len() < len(s) {