// Copyright 2010 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.package runtimeimport ()// The Error interface identifies a run time error.typeErrorinterface {error// RuntimeError is a no-op function but // serves to distinguish types that are run time // errors from ordinary errors: a type is a // run time error if it has a RuntimeError method. RuntimeError()}// A TypeAssertionError explains a failed type assertion.typeTypeAssertionErrorstruct { _interface *_type concrete *_type asserted *_type missingMethod string// one method needed by Interface, missing from Concrete}func (*TypeAssertionError) () {}func ( *TypeAssertionError) () string { := "interface"if ._interface != nil { = toRType(._interface).string() } := toRType(.asserted).string()if .concrete == nil {return"interface conversion: " + + " is nil, not " + } := toRType(.concrete).string()if .missingMethod == "" { := "interface conversion: " + + " is " + + ", not " + if == {// provide slightly clearer error messageiftoRType(.concrete).pkgpath() != toRType(.asserted).pkgpath() { += " (types from different packages)" } else { += " (types from different scopes)" } }return }return"interface conversion: " + + " is not " + +": missing method " + .missingMethod}// itoa converts val to a decimal representation. The result is// written somewhere within buf and the location of the result is returned.// buf must be at least 20 bytes.////go:nosplitfunc itoa( []byte, uint64) []byte { := len() - 1for >= 10 { [] = byte(%10 + '0') -- /= 10 } [] = byte( + '0')return [:]}// An errorString represents a runtime error described by a single string.type errorString stringfunc ( errorString) () {}func ( errorString) () string {return"runtime error: " + string()}type errorAddressString struct { msg string// error message addr uintptr// memory address where the error occurred}func ( errorAddressString) () {}func ( errorAddressString) () string {return"runtime error: " + .msg}// Addr returns the memory address where a fault occurred.// The address provided is best-effort.// The veracity of the result may depend on the platform.// Errors providing this method will only be returned as// a result of using [runtime/debug.SetPanicOnFault].func ( errorAddressString) () uintptr {return .addr}// plainError represents a runtime error described a string without// the prefix "runtime error: " after invoking errorString.Error().// See Issue #14965.type plainError stringfunc ( plainError) () {}func ( plainError) () string {returnstring()}// A boundsError represents an indexing or slicing operation gone wrong.type boundsError struct { x int64 y int// Values in an index or slice expression can be signed or unsigned. // That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1. // Instead, we keep track of whether x should be interpreted as signed or unsigned. // y is known to be nonnegative and to fit in an int. signed bool code boundsErrorCode}type boundsErrorCode uint8const ( boundsIndex boundsErrorCode = iota// s[x], 0 <= x < len(s) failed boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed boundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen) boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed boundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen) boundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen) boundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed// Note: in the above, len(s) and cap(s) are stored in y)// boundsErrorFmts provide error text for various out-of-bounds panics.// Note: if you change these strings, you should adjust the size of the buffer// in boundsError.Error below as well.var boundsErrorFmts = [...]string{boundsIndex: "index out of range [%x] with length %y",boundsSliceAlen: "slice bounds out of range [:%x] with length %y",boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",boundsSliceB: "slice bounds out of range [%x:%y]",boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",boundsSlice3B: "slice bounds out of range [:%x:%y]",boundsSlice3C: "slice bounds out of range [%x:%y:]",boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",}// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.var boundsNegErrorFmts = [...]string{boundsIndex: "index out of range [%x]",boundsSliceAlen: "slice bounds out of range [:%x]",boundsSliceAcap: "slice bounds out of range [:%x]",boundsSliceB: "slice bounds out of range [%x:]",boundsSlice3Alen: "slice bounds out of range [::%x]",boundsSlice3Acap: "slice bounds out of range [::%x]",boundsSlice3B: "slice bounds out of range [:%x:]",boundsSlice3C: "slice bounds out of range [%x::]",}func ( boundsError) () {}func appendIntStr( []byte, int64, bool) []byte {if && < 0 { = append(, '-') = - }var [20]byte = append(, itoa([:], uint64())...)return}func ( boundsError) () string { := boundsErrorFmts[.code]if .signed && .x < 0 { = boundsNegErrorFmts[.code] }// max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y" // x can be at most 20 characters. y can be at most 19. := make([]byte, 0, 100) = append(, "runtime error: "...)for := 0; < len(); ++ { := []if != '%' { = append(, )continue } ++switch [] {case'x': = appendIntStr(, .x, .signed)case'y': = appendIntStr(, int64(.y), true) } }returnstring()}type stringer interface { String() string}// printpanicval prints an argument passed to panic.// If panic is called with a value that has a String or Error method,// it has already been converted into a string by preprintpanics.//// To ensure that the traceback can be unambiguously parsed even when// the panic value contains "\ngoroutine" and other stack-like// strings, newlines in the string representation of v are replaced by// "\n\t".func printpanicval( any) {switch v := .(type) {casenil:print("nil")casebool:print()caseint:print()caseint8:print()caseint16:print()caseint32:print()caseint64:print()caseuint:print()caseuint8:print()caseuint16:print()caseuint32:print()caseuint64:print()caseuintptr:print()casefloat32:print()casefloat64:print()casecomplex64:print()casecomplex128:print()casestring:printindented()default:printanycustomtype() }}// Invariant: each newline in the string representation is followed by a tab.func printanycustomtype( any) { := efaceOf(&) := toRType(._type).string()switch ._type.Kind_ {caseabi.String:print(, `("`)printindented(*(*string)(.data))print(`")`)caseabi.Bool:print(, "(", *(*bool)(.data), ")")caseabi.Int:print(, "(", *(*int)(.data), ")")caseabi.Int8:print(, "(", *(*int8)(.data), ")")caseabi.Int16:print(, "(", *(*int16)(.data), ")")caseabi.Int32:print(, "(", *(*int32)(.data), ")")caseabi.Int64:print(, "(", *(*int64)(.data), ")")caseabi.Uint:print(, "(", *(*uint)(.data), ")")caseabi.Uint8:print(, "(", *(*uint8)(.data), ")")caseabi.Uint16:print(, "(", *(*uint16)(.data), ")")caseabi.Uint32:print(, "(", *(*uint32)(.data), ")")caseabi.Uint64:print(, "(", *(*uint64)(.data), ")")caseabi.Uintptr:print(, "(", *(*uintptr)(.data), ")")caseabi.Float32:print(, "(", *(*float32)(.data), ")")caseabi.Float64:print(, "(", *(*float64)(.data), ")")caseabi.Complex64:print(, *(*complex64)(.data))caseabi.Complex128:print(, *(*complex128)(.data))default:print("(", , ") ", .data) }}// printindented prints s, replacing "\n" with "\n\t".func printindented( string) {for { := bytealg.IndexByteString(, '\n')if < 0 {break } += len("\n")print([:])print("\t") = [:] }print()}// panicwrap generates a panic for a call to a wrapped value method// with a nil pointer receiver.//// It is called from the generated wrapper code.func panicwrap() { := getcallerpc() := funcNameForPrint(funcname(findfunc()))// name is something like "main.(*T).F". // We want to extract pkg ("main"), typ ("T"), and meth ("F"). // Do it by finding the parens. := bytealg.IndexByteString(, '(')if < 0 {throw("panicwrap: no ( in " + ) } := [:-1]if +2 >= len() || [-1:+2] != ".(*" {throw("panicwrap: unexpected string after package name: " + ) } = [+2:] = bytealg.IndexByteString(, ')')if < 0 {throw("panicwrap: no ) in " + ) }if +2 >= len() || [:+2] != ")." {throw("panicwrap: unexpected string after type name: " + ) } := [:] := [+2:]panic(plainError("value method " + + "." + + "." + + " called using nil *" + + " pointer"))}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.