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