]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/types2/errors.go
go/types, types2: remove local version processing in favor of go/version
[gostls13.git] / src / cmd / compile / internal / types2 / errors.go
index 2a3e88a2fe095f89d4ef1721552b0da8ea99cdfd..b8414b48498f242b088f5f8d1517156de31db1e4 100644 (file)
@@ -10,15 +10,12 @@ import (
        "bytes"
        "cmd/compile/internal/syntax"
        "fmt"
+       . "internal/types/errors"
        "runtime"
        "strconv"
        "strings"
 )
 
-func unimplemented() {
-       panic("unimplemented")
-}
-
 func assert(p bool) {
        if !p {
                msg := "assertion failed"
@@ -39,6 +36,7 @@ func unreachable() {
 // To report an error_, call Checker.report.
 type error_ struct {
        desc []errorDesc
+       code Code
        soft bool // TODO(gri) eventually determine this from an error code
 }
 
@@ -64,7 +62,7 @@ func (err *error_) msg(qf Qualifier) string {
        if err.empty() {
                return "no error"
        }
-       var buf bytes.Buffer
+       var buf strings.Builder
        for i := range err.desc {
                p := &err.desc[i]
                if i > 0 {
@@ -89,10 +87,10 @@ func (err *error_) String() string {
 // errorf adds formatted error information to err.
 // It may be called multiple times to provide additional information.
 func (err *error_) errorf(at poser, format string, args ...interface{}) {
-       err.desc = append(err.desc, errorDesc{posFor(at), format, args})
+       err.desc = append(err.desc, errorDesc{atPos(at), format, args})
 }
 
-func sprintf(qf Qualifier, debug bool, format string, args ...interface{}) string {
+func sprintf(qf Qualifier, tpSubscripts bool, format string, args ...interface{}) string {
        for i, arg := range args {
                switch a := arg.(type) {
                case nil:
@@ -106,7 +104,7 @@ func sprintf(qf Qualifier, debug bool, format string, args ...interface{}) strin
                case syntax.Expr:
                        arg = syntax.String(a)
                case []syntax.Expr:
-                       var buf bytes.Buffer
+                       var buf strings.Builder
                        buf.WriteByte('[')
                        for i, x := range a {
                                if i > 0 {
@@ -119,26 +117,34 @@ func sprintf(qf Qualifier, debug bool, format string, args ...interface{}) strin
                case Object:
                        arg = ObjectString(a, qf)
                case Type:
-                       arg = typeString(a, qf, debug)
+                       var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
+                       w.typ(a)
+                       arg = buf.String()
                case []Type:
                        var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
                        buf.WriteByte('[')
                        for i, x := range a {
                                if i > 0 {
                                        buf.WriteString(", ")
                                }
-                               buf.WriteString(typeString(x, qf, debug))
+                               w.typ(x)
                        }
                        buf.WriteByte(']')
                        arg = buf.String()
                case []*TypeParam:
                        var buf bytes.Buffer
+                       w := newTypeWriter(&buf, qf)
+                       w.tpSubscripts = tpSubscripts
                        buf.WriteByte('[')
                        for i, x := range a {
                                if i > 0 {
                                        buf.WriteString(", ")
                                }
-                               buf.WriteString(typeString(x, qf, debug)) // use typeString so we get subscripts when debugging
+                               w.typ(x)
                        }
                        buf.WriteByte(']')
                        arg = buf.String()
@@ -198,7 +204,7 @@ func (check *Checker) report(err *error_) {
        if err.empty() {
                panic("no error to report")
        }
-       check.err(err.pos(), err.msg(check.qualifier), err.soft)
+       check.err(err.pos(), err.code, err.msg(check.qualifier), err.soft)
 }
 
 func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
@@ -214,7 +220,14 @@ func (check *Checker) dump(format string, args ...interface{}) {
        fmt.Println(sprintf(check.qualifier, true, format, args...))
 }
 
-func (check *Checker) err(at poser, msg string, soft bool) {
+func (check *Checker) err(at poser, code Code, msg string, soft bool) {
+       switch code {
+       case InvalidSyntaxTree:
+               msg = "invalid syntax tree: " + msg
+       case 0:
+               panic("no error code provided")
+       }
+
        // Cheap trick: Don't report errors with messages containing
        // "invalid operand" or "invalid type" as those tend to be
        // follow-on errors which don't add useful information. Only
@@ -224,7 +237,7 @@ func (check *Checker) err(at poser, msg string, soft bool) {
                return
        }
 
-       pos := posFor(at)
+       pos := atPos(at)
 
        // If we are encountering an error while evaluating an inherited
        // constant initialization expression, pos is the position of in
@@ -237,7 +250,17 @@ func (check *Checker) err(at poser, msg string, soft bool) {
                pos = check.errpos
        }
 
-       err := Error{pos, stripAnnotations(msg), msg, soft}
+       // If we have a URL for error codes, add a link to the first line.
+       if code != 0 && check.conf.ErrorURL != "" {
+               u := fmt.Sprintf(check.conf.ErrorURL, code)
+               if i := strings.Index(msg, "\n"); i >= 0 {
+                       msg = msg[:i] + u + msg[i:]
+               } else {
+                       msg += u
+               }
+       }
+
+       err := Error{pos, stripAnnotations(msg), msg, soft, code}
        if check.firstErr == nil {
                check.firstErr = err
        }
@@ -254,7 +277,6 @@ func (check *Checker) err(at poser, msg string, soft bool) {
 }
 
 const (
-       invalidAST = "invalid AST: "
        invalidArg = "invalid argument: "
        invalidOp  = "invalid operation: "
 )
@@ -263,30 +285,26 @@ type poser interface {
        Pos() syntax.Pos
 }
 
-func (check *Checker) error(at poser, msg string) {
-       check.err(at, msg, false)
+func (check *Checker) error(at poser, code Code, msg string) {
+       check.err(at, code, msg, false)
 }
 
-func (check *Checker) errorf(at poser, format string, args ...interface{}) {
-       check.err(at, check.sprintf(format, args...), false)
+func (check *Checker) errorf(at poser, code Code, format string, args ...interface{}) {
+       check.err(at, code, check.sprintf(format, args...), false)
 }
 
-func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
-       check.err(at, check.sprintf(format, args...), true)
+func (check *Checker) softErrorf(at poser, code Code, format string, args ...interface{}) {
+       check.err(at, code, check.sprintf(format, args...), true)
 }
 
-func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
+func (check *Checker) versionErrorf(at poser, v goVersion, format string, args ...interface{}) {
        msg := check.sprintf(format, args...)
-       if check.conf.CompilerErrorMessages {
-               msg = fmt.Sprintf("%s requires %s or later (-lang was set to %s; check go.mod)", msg, goVersion, check.conf.GoVersion)
-       } else {
-               msg = fmt.Sprintf("%s requires %s or later", msg, goVersion)
-       }
-       check.err(at, msg, true)
+       msg = fmt.Sprintf("%s requires %s or later", msg, v)
+       check.err(at, UnsupportedFeature, msg, true)
 }
 
-// posFor reports the left (= start) position of at.
-func posFor(at poser) syntax.Pos {
+// atPos reports the left (= start) position of at.
+func atPos(at poser) syntax.Pos {
        switch x := at.(type) {
        case *operand:
                if x.expr != nil {
@@ -300,16 +318,15 @@ func posFor(at poser) syntax.Pos {
 
 // stripAnnotations removes internal (type) annotations from s.
 func stripAnnotations(s string) string {
-       // Would like to use strings.Builder but it's not available in Go 1.4.
-       var b bytes.Buffer
+       var buf strings.Builder
        for _, r := range s {
                // strip #'s and subscript digits
                if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-                       b.WriteRune(r)
+                       buf.WriteRune(r)
                }
        }
-       if b.Len() < len(s) {
-               return b.String()
+       if buf.Len() < len(s) {
+               return buf.String()
        }
        return s
 }