Source file
src/runtime/error.go
Documentation: runtime
1
2
3
4
5 package runtime
6
7 import "internal/bytealg"
8
9
10 type Error interface {
11 error
12
13
14
15
16
17 RuntimeError()
18 }
19
20
21 type TypeAssertionError struct {
22 _interface *_type
23 concrete *_type
24 asserted *_type
25 missingMethod string
26 }
27
28 func (*TypeAssertionError) RuntimeError() {}
29
30 func (e *TypeAssertionError) Error() string {
31 inter := "interface"
32 if e._interface != nil {
33 inter = toRType(e._interface).string()
34 }
35 as := toRType(e.asserted).string()
36 if e.concrete == nil {
37 return "interface conversion: " + inter + " is nil, not " + as
38 }
39 cs := toRType(e.concrete).string()
40 if e.missingMethod == "" {
41 msg := "interface conversion: " + inter + " is " + cs + ", not " + as
42 if cs == as {
43
44 if toRType(e.concrete).pkgpath() != toRType(e.asserted).pkgpath() {
45 msg += " (types from different packages)"
46 } else {
47 msg += " (types from different scopes)"
48 }
49 }
50 return msg
51 }
52 return "interface conversion: " + cs + " is not " + as +
53 ": missing method " + e.missingMethod
54 }
55
56
57
58
59
60
61 func itoa(buf []byte, val uint64) []byte {
62 i := len(buf) - 1
63 for val >= 10 {
64 buf[i] = byte(val%10 + '0')
65 i--
66 val /= 10
67 }
68 buf[i] = byte(val + '0')
69 return buf[i:]
70 }
71
72
73 type errorString string
74
75 func (e errorString) RuntimeError() {}
76
77 func (e errorString) Error() string {
78 return "runtime error: " + string(e)
79 }
80
81 type errorAddressString struct {
82 msg string
83 addr uintptr
84 }
85
86 func (e errorAddressString) RuntimeError() {}
87
88 func (e errorAddressString) Error() string {
89 return "runtime error: " + e.msg
90 }
91
92
93
94
95
96
97 func (e errorAddressString) Addr() uintptr {
98 return e.addr
99 }
100
101
102
103
104 type plainError string
105
106 func (e plainError) RuntimeError() {}
107
108 func (e plainError) Error() string {
109 return string(e)
110 }
111
112
113 type boundsError struct {
114 x int64
115 y int
116
117
118
119
120 signed bool
121 code boundsErrorCode
122 }
123
124 type boundsErrorCode uint8
125
126 const (
127 boundsIndex boundsErrorCode = iota
128
129 boundsSliceAlen
130 boundsSliceAcap
131 boundsSliceB
132
133 boundsSlice3Alen
134 boundsSlice3Acap
135 boundsSlice3B
136 boundsSlice3C
137
138 boundsConvert
139
140 )
141
142
143
144
145 var boundsErrorFmts = [...]string{
146 boundsIndex: "index out of range [%x] with length %y",
147 boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
148 boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
149 boundsSliceB: "slice bounds out of range [%x:%y]",
150 boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
151 boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
152 boundsSlice3B: "slice bounds out of range [:%x:%y]",
153 boundsSlice3C: "slice bounds out of range [%x:%y:]",
154 boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
155 }
156
157
158 var boundsNegErrorFmts = [...]string{
159 boundsIndex: "index out of range [%x]",
160 boundsSliceAlen: "slice bounds out of range [:%x]",
161 boundsSliceAcap: "slice bounds out of range [:%x]",
162 boundsSliceB: "slice bounds out of range [%x:]",
163 boundsSlice3Alen: "slice bounds out of range [::%x]",
164 boundsSlice3Acap: "slice bounds out of range [::%x]",
165 boundsSlice3B: "slice bounds out of range [:%x:]",
166 boundsSlice3C: "slice bounds out of range [%x::]",
167 }
168
169 func (e boundsError) RuntimeError() {}
170
171 func appendIntStr(b []byte, v int64, signed bool) []byte {
172 if signed && v < 0 {
173 b = append(b, '-')
174 v = -v
175 }
176 var buf [20]byte
177 b = append(b, itoa(buf[:], uint64(v))...)
178 return b
179 }
180
181 func (e boundsError) Error() string {
182 fmt := boundsErrorFmts[e.code]
183 if e.signed && e.x < 0 {
184 fmt = boundsNegErrorFmts[e.code]
185 }
186
187
188 b := make([]byte, 0, 100)
189 b = append(b, "runtime error: "...)
190 for i := 0; i < len(fmt); i++ {
191 c := fmt[i]
192 if c != '%' {
193 b = append(b, c)
194 continue
195 }
196 i++
197 switch fmt[i] {
198 case 'x':
199 b = appendIntStr(b, e.x, e.signed)
200 case 'y':
201 b = appendIntStr(b, int64(e.y), true)
202 }
203 }
204 return string(b)
205 }
206
207 type stringer interface {
208 String() string
209 }
210
211
212
213
214 func printany(i any) {
215 switch v := i.(type) {
216 case nil:
217 print("nil")
218 case bool:
219 print(v)
220 case int:
221 print(v)
222 case int8:
223 print(v)
224 case int16:
225 print(v)
226 case int32:
227 print(v)
228 case int64:
229 print(v)
230 case uint:
231 print(v)
232 case uint8:
233 print(v)
234 case uint16:
235 print(v)
236 case uint32:
237 print(v)
238 case uint64:
239 print(v)
240 case uintptr:
241 print(v)
242 case float32:
243 print(v)
244 case float64:
245 print(v)
246 case complex64:
247 print(v)
248 case complex128:
249 print(v)
250 case string:
251 print(v)
252 default:
253 printanycustomtype(i)
254 }
255 }
256
257 func printanycustomtype(i any) {
258 eface := efaceOf(&i)
259 typestring := toRType(eface._type).string()
260
261 switch eface._type.Kind_ {
262 case kindString:
263 print(typestring, `("`, *(*string)(eface.data), `")`)
264 case kindBool:
265 print(typestring, "(", *(*bool)(eface.data), ")")
266 case kindInt:
267 print(typestring, "(", *(*int)(eface.data), ")")
268 case kindInt8:
269 print(typestring, "(", *(*int8)(eface.data), ")")
270 case kindInt16:
271 print(typestring, "(", *(*int16)(eface.data), ")")
272 case kindInt32:
273 print(typestring, "(", *(*int32)(eface.data), ")")
274 case kindInt64:
275 print(typestring, "(", *(*int64)(eface.data), ")")
276 case kindUint:
277 print(typestring, "(", *(*uint)(eface.data), ")")
278 case kindUint8:
279 print(typestring, "(", *(*uint8)(eface.data), ")")
280 case kindUint16:
281 print(typestring, "(", *(*uint16)(eface.data), ")")
282 case kindUint32:
283 print(typestring, "(", *(*uint32)(eface.data), ")")
284 case kindUint64:
285 print(typestring, "(", *(*uint64)(eface.data), ")")
286 case kindUintptr:
287 print(typestring, "(", *(*uintptr)(eface.data), ")")
288 case kindFloat32:
289 print(typestring, "(", *(*float32)(eface.data), ")")
290 case kindFloat64:
291 print(typestring, "(", *(*float64)(eface.data), ")")
292 case kindComplex64:
293 print(typestring, *(*complex64)(eface.data))
294 case kindComplex128:
295 print(typestring, *(*complex128)(eface.data))
296 default:
297 print("(", typestring, ") ", eface.data)
298 }
299 }
300
301
302
303
304
305 func panicwrap() {
306 pc := getcallerpc()
307 name := funcNameForPrint(funcname(findfunc(pc)))
308
309
310
311 i := bytealg.IndexByteString(name, '(')
312 if i < 0 {
313 throw("panicwrap: no ( in " + name)
314 }
315 pkg := name[:i-1]
316 if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
317 throw("panicwrap: unexpected string after package name: " + name)
318 }
319 name = name[i+2:]
320 i = bytealg.IndexByteString(name, ')')
321 if i < 0 {
322 throw("panicwrap: no ) in " + name)
323 }
324 if i+2 >= len(name) || name[i:i+2] != ")." {
325 throw("panicwrap: unexpected string after type name: " + name)
326 }
327 typ := name[:i]
328 meth := name[i+2:]
329 panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
330 }
331
View as plain text