1
2
3
4
5
6
7 package types2
8
9 import (
10 "cmd/compile/internal/syntax"
11 "fmt"
12 . "internal/types/errors"
13 "runtime"
14 "strings"
15 )
16
17 func assert(p bool) {
18 if !p {
19 msg := "assertion failed"
20
21
22 if _, file, line, ok := runtime.Caller(1); ok {
23 msg = fmt.Sprintf("%s:%d: %s", file, line, msg)
24 }
25 panic(msg)
26 }
27 }
28
29
30 type errorDesc struct {
31 pos syntax.Pos
32 msg string
33 }
34
35
36
37
38 type error_ struct {
39 check *Checker
40 desc []errorDesc
41 code Code
42 soft bool
43 }
44
45
46 func (check *Checker) newError(code Code) *error_ {
47 if code == 0 {
48 panic("error code must not be 0")
49 }
50 return &error_{check: check, code: code}
51 }
52
53
54
55
56
57
58
59 func (err *error_) addf(at poser, format string, args ...interface{}) {
60 err.desc = append(err.desc, errorDesc{atPos(at), err.check.sprintf(format, args...)})
61 }
62
63
64 func (err *error_) addAltDecl(obj Object) {
65 if pos := obj.Pos(); pos.IsKnown() {
66
67
68
69 err.addf(obj, "other declaration of %s", obj.Name())
70 }
71 }
72
73 func (err *error_) empty() bool {
74 return err.desc == nil
75 }
76
77 func (err *error_) pos() syntax.Pos {
78 if err.empty() {
79 return nopos
80 }
81 return err.desc[0].pos
82 }
83
84
85 func (err *error_) msg() string {
86 if err.empty() {
87 return "no error"
88 }
89
90 var buf strings.Builder
91 for i := range err.desc {
92 p := &err.desc[i]
93 if i > 0 {
94 fmt.Fprint(&buf, "\n\t")
95 if p.pos.IsKnown() {
96 fmt.Fprintf(&buf, "%s: ", p.pos)
97 }
98 }
99 buf.WriteString(p.msg)
100 }
101 return buf.String()
102 }
103
104
105 func (err *error_) report() {
106 if err.empty() {
107 panic("no error")
108 }
109
110
111
112
113
114
115 check := err.check
116 if check.firstErr != nil {
117
118 msg := err.desc[0].msg
119 if strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0 {
120 return
121 }
122 }
123
124 if check.conf.Trace {
125 check.trace(err.pos(), "ERROR: %s (code = %d)", err.desc[0].msg, err.code)
126 }
127
128
129
130
131 multiError := false
132 if !isTypes2 {
133 for i := 1; i < len(err.desc); i++ {
134 if err.desc[i].pos.IsKnown() {
135 multiError = true
136 break
137 }
138 }
139 }
140
141 if multiError {
142 for i := range err.desc {
143 p := &err.desc[i]
144 check.handleError(i, p.pos, err.code, p.msg, err.soft)
145 }
146 } else {
147 check.handleError(0, err.pos(), err.code, err.msg(), err.soft)
148 }
149
150
151 err.desc = nil
152 }
153
154
155 func (check *Checker) handleError(index int, pos syntax.Pos, code Code, msg string, soft bool) {
156 assert(code != 0)
157
158 if index == 0 {
159
160
161
162
163
164
165 if check.errpos.Pos().IsKnown() {
166 assert(check.iota != nil)
167 pos = check.errpos
168 }
169
170
171 if code == InvalidSyntaxTree {
172 msg = "invalid syntax tree: " + msg
173 }
174
175
176 if check.conf.ErrorURL != "" {
177 url := fmt.Sprintf(check.conf.ErrorURL, code)
178 if i := strings.Index(msg, "\n"); i >= 0 {
179 msg = msg[:i] + url + msg[i:]
180 } else {
181 msg += url
182 }
183 }
184 } else {
185
186
187 msg = "\t" + msg
188 }
189
190 e := Error{
191 Pos: pos,
192 Msg: stripAnnotations(msg),
193 Full: msg,
194 Soft: soft,
195 Code: code,
196 }
197
198 if check.firstErr == nil {
199 check.firstErr = e
200 }
201
202 f := check.conf.Error
203 if f == nil {
204 panic(bailout{})
205 }
206 f(e)
207 }
208
209 const (
210 invalidArg = "invalid argument: "
211 invalidOp = "invalid operation: "
212 )
213
214
215 type poser interface {
216 Pos() syntax.Pos
217 }
218
219 func (check *Checker) error(at poser, code Code, msg string) {
220 err := check.newError(code)
221 err.addf(at, "%s", msg)
222 err.report()
223 }
224
225 func (check *Checker) errorf(at poser, code Code, format string, args ...any) {
226 err := check.newError(code)
227 err.addf(at, format, args...)
228 err.report()
229 }
230
231 func (check *Checker) softErrorf(at poser, code Code, format string, args ...any) {
232 err := check.newError(code)
233 err.addf(at, format, args...)
234 err.soft = true
235 err.report()
236 }
237
238 func (check *Checker) versionErrorf(at poser, v goVersion, format string, args ...any) {
239 msg := check.sprintf(format, args...)
240 err := check.newError(UnsupportedFeature)
241 err.addf(at, "%s requires %s or later", msg, v)
242 err.report()
243 }
244
245
246 func atPos(at poser) syntax.Pos {
247 switch x := at.(type) {
248 case *operand:
249 if x.expr != nil {
250 return syntax.StartPos(x.expr)
251 }
252 case syntax.Node:
253 return syntax.StartPos(x)
254 }
255 return at.Pos()
256 }
257
View as plain text