package runtime
import "internal/bytealg"
type Error interface {
error
RuntimeError()
}
type TypeAssertionError struct {
_interface *_type
concrete *_type
asserted *_type
missingMethod string
}
func (*TypeAssertionError ) RuntimeError () {}
func (e *TypeAssertionError ) Error () string {
inter := "interface"
if e ._interface != nil {
inter = toRType (e ._interface ).string ()
}
as := toRType (e .asserted ).string ()
if e .concrete == nil {
return "interface conversion: " + inter + " is nil, not " + as
}
cs := toRType (e .concrete ).string ()
if e .missingMethod == "" {
msg := "interface conversion: " + inter + " is " + cs + ", not " + as
if cs == as {
if toRType (e .concrete ).pkgpath () != toRType (e .asserted ).pkgpath () {
msg += " (types from different packages)"
} else {
msg += " (types from different scopes)"
}
}
return msg
}
return "interface conversion: " + cs + " is not " + as +
": missing method " + e .missingMethod
}
func itoa (buf []byte , val uint64 ) []byte {
i := len (buf ) - 1
for val >= 10 {
buf [i ] = byte (val %10 + '0' )
i --
val /= 10
}
buf [i ] = byte (val + '0' )
return buf [i :]
}
type errorString string
func (e errorString ) RuntimeError () {}
func (e errorString ) Error () string {
return "runtime error: " + string (e )
}
type errorAddressString struct {
msg string
addr uintptr
}
func (e errorAddressString ) RuntimeError () {}
func (e errorAddressString ) Error () string {
return "runtime error: " + e .msg
}
func (e errorAddressString ) Addr () uintptr {
return e .addr
}
type plainError string
func (e plainError ) RuntimeError () {}
func (e plainError ) Error () string {
return string (e )
}
type boundsError struct {
x int64
y int
signed bool
code boundsErrorCode
}
type boundsErrorCode uint8
const (
boundsIndex boundsErrorCode = iota
boundsSliceAlen
boundsSliceAcap
boundsSliceB
boundsSlice3Alen
boundsSlice3Acap
boundsSlice3B
boundsSlice3C
boundsConvert
)
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" ,
}
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 (e boundsError ) RuntimeError () {}
func appendIntStr (b []byte , v int64 , signed bool ) []byte {
if signed && v < 0 {
b = append (b , '-' )
v = -v
}
var buf [20 ]byte
b = append (b , itoa (buf [:], uint64 (v ))...)
return b
}
func (e boundsError ) Error () string {
fmt := boundsErrorFmts [e .code ]
if e .signed && e .x < 0 {
fmt = boundsNegErrorFmts [e .code ]
}
b := make ([]byte , 0 , 100 )
b = append (b , "runtime error: " ...)
for i := 0 ; i < len (fmt ); i ++ {
c := fmt [i ]
if c != '%' {
b = append (b , c )
continue
}
i ++
switch fmt [i ] {
case 'x' :
b = appendIntStr (b , e .x , e .signed )
case 'y' :
b = appendIntStr (b , int64 (e .y ), true )
}
}
return string (b )
}
type stringer interface {
String () string
}
func printany (i any ) {
switch v := i .(type ) {
case nil :
print ("nil" )
case bool :
print (v )
case int :
print (v )
case int8 :
print (v )
case int16 :
print (v )
case int32 :
print (v )
case int64 :
print (v )
case uint :
print (v )
case uint8 :
print (v )
case uint16 :
print (v )
case uint32 :
print (v )
case uint64 :
print (v )
case uintptr :
print (v )
case float32 :
print (v )
case float64 :
print (v )
case complex64 :
print (v )
case complex128 :
print (v )
case string :
print (v )
default :
printanycustomtype (i )
}
}
func printanycustomtype (i any ) {
eface := efaceOf (&i )
typestring := toRType (eface ._type ).string ()
switch eface ._type .Kind_ {
case kindString :
print (typestring , `("` , *(*string )(eface .data ), `")` )
case kindBool :
print (typestring , "(" , *(*bool )(eface .data ), ")" )
case kindInt :
print (typestring , "(" , *(*int )(eface .data ), ")" )
case kindInt8 :
print (typestring , "(" , *(*int8 )(eface .data ), ")" )
case kindInt16 :
print (typestring , "(" , *(*int16 )(eface .data ), ")" )
case kindInt32 :
print (typestring , "(" , *(*int32 )(eface .data ), ")" )
case kindInt64 :
print (typestring , "(" , *(*int64 )(eface .data ), ")" )
case kindUint :
print (typestring , "(" , *(*uint )(eface .data ), ")" )
case kindUint8 :
print (typestring , "(" , *(*uint8 )(eface .data ), ")" )
case kindUint16 :
print (typestring , "(" , *(*uint16 )(eface .data ), ")" )
case kindUint32 :
print (typestring , "(" , *(*uint32 )(eface .data ), ")" )
case kindUint64 :
print (typestring , "(" , *(*uint64 )(eface .data ), ")" )
case kindUintptr :
print (typestring , "(" , *(*uintptr )(eface .data ), ")" )
case kindFloat32 :
print (typestring , "(" , *(*float32 )(eface .data ), ")" )
case kindFloat64 :
print (typestring , "(" , *(*float64 )(eface .data ), ")" )
case kindComplex64 :
print (typestring , *(*complex64 )(eface .data ))
case kindComplex128 :
print (typestring , *(*complex128 )(eface .data ))
default :
print ("(" , typestring , ") " , eface .data )
}
}
func panicwrap () {
pc := getcallerpc ()
name := funcNameForPrint (funcname (findfunc (pc )))
i := bytealg .IndexByteString (name , '(' )
if i < 0 {
throw ("panicwrap: no ( in " + name )
}
pkg := name [:i -1 ]
if i +2 >= len (name ) || name [i -1 :i +2 ] != ".(*" {
throw ("panicwrap: unexpected string after package name: " + name )
}
name = name [i +2 :]
i = bytealg .IndexByteString (name , ')' )
if i < 0 {
throw ("panicwrap: no ) in " + name )
}
if i +2 >= len (name ) || name [i :i +2 ] != ")." {
throw ("panicwrap: unexpected string after type name: " + name )
}
typ := name [:i ]
meth := name [i +2 :]
panic (plainError ("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer" ))
}
The pages are generated with Golds v0.6.7 . (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 @Go100and1 (reachable from the left QR code) to get the latest news of Golds .