// 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 { = ._interface.string() } := .asserted.string()if .concrete == nil {return"interface conversion: " + + " is nil, not " + } := .concrete.string()if .missingMethod == "" { := "interface conversion: " + + " is " + + ", not " + if == {// provide slightly clearer error messageif .concrete.pkgpath() != .asserted.pkgpath() { += " (types from different packages)" } else { += " (types from different scopes)" } }return }return"interface conversion: " + + " is not " + +": missing method " + .missingMethod}//go:nosplit// 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.func ( []byte, uint64) []byte { := len() - 1for >= 10 { [] = byte(%10 + '0') -- /= 10 } [] = byte( + '0')return [:]}// An errorString represents a runtime error described by a single string.typeerrorStringstringfunc ( errorString) () {}func ( errorString) () string {return"runtime error: " + string()}typeerrorAddressStringstruct { 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.typeplainErrorstringfunc ( plainError) () {}func ( plainError) () string {returnstring()}// A boundsError represents an indexing or slicing operation gone wrong.typeboundsErrorstruct { 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}typeboundsErrorCodeuint8const (boundsIndexboundsErrorCode = iota// s[x], 0 <= x < len(s) failedboundsSliceAlen// s[?:x], 0 <= x <= len(s) failedboundsSliceAcap// s[?:x], 0 <= x <= cap(s) failedboundsSliceB// s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)boundsSlice3Alen// s[?:?:x], 0 <= x <= len(s) failedboundsSlice3Acap// s[?:?:x], 0 <= x <= cap(s) failedboundsSlice3B// 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)// 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.varboundsErrorFmts = [...]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:]",}// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.varboundsNegErrorFmts = [...]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 ( []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()}typestringerinterface {String() string}// printany 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.func ( interface{}) {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:print()default:printanycustomtype() }}func ( interface{}) { := efaceOf(&) := ._type.string()switch ._type.kind {casekindString:print(, `("`, *(*string)(.data), `")`)casekindBool:print(, "(", *(*bool)(.data), ")")casekindInt:print(, "(", *(*int)(.data), ")")casekindInt8:print(, "(", *(*int8)(.data), ")")casekindInt16:print(, "(", *(*int16)(.data), ")")casekindInt32:print(, "(", *(*int32)(.data), ")")casekindInt64:print(, "(", *(*int64)(.data), ")")casekindUint:print(, "(", *(*uint)(.data), ")")casekindUint8:print(, "(", *(*uint8)(.data), ")")casekindUint16:print(, "(", *(*uint16)(.data), ")")casekindUint32:print(, "(", *(*uint32)(.data), ")")casekindUint64:print(, "(", *(*uint64)(.data), ")")casekindUintptr:print(, "(", *(*uintptr)(.data), ")")casekindFloat32:print(, "(", *(*float32)(.data), ")")casekindFloat64:print(, "(", *(*float64)(.data), ")")casekindComplex64:print(, *(*complex64)(.data))casekindComplex128:print(, *(*complex128)(.data))default:print("(", , ") ", .data) }}// 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 () { := getcallerpc() := 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"))}