1// Copyright 2010 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime
6
7import "unsafe"
8
9// The Error interface identifies a run time error.
10type Error interface {
11	error
12
13	// RuntimeError is a no-op function but
14	// serves to distinguish types that are run time
15	// errors from ordinary errors: a type is a
16	// run time error if it has a RuntimeError method.
17	RuntimeError()
18}
19
20// A TypeAssertionError explains a failed type assertion.
21type TypeAssertionError struct {
22	_interface    *_type
23	concrete      *_type
24	asserted      *_type
25	missingMethod string // one method needed by Interface, missing from Concrete
26}
27
28func (*TypeAssertionError) RuntimeError() {}
29
30func (e *TypeAssertionError) Error() string {
31	inter := "interface"
32	if e._interface != nil {
33		inter = e._interface.string()
34	}
35	as := e.asserted.string()
36	if e.concrete == nil {
37		return "interface conversion: " + inter + " is nil, not " + as
38	}
39	cs := e.concrete.string()
40	if e.missingMethod == "" {
41		msg := "interface conversion: " + inter + " is " + cs + ", not " + as
42		if cs == as {
43			// provide slightly clearer error message
44			if e.concrete.pkgpath() != 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// Remove quoted strings from gccgo reflection strings.
57func unquote(s string) string {
58	ls := len(s)
59	var i int
60	for i = 0; i < ls; i++ {
61		if s[i] == '\t' {
62			break
63		}
64	}
65	if i == ls {
66		return s
67	}
68	var q bool
69	r := make([]byte, len(s))
70	j := 0
71	for i = 0; i < ls; i++ {
72		if s[i] == '\t' {
73			q = !q
74		} else if !q {
75			r[j] = s[i]
76			j++
77		}
78	}
79	return string(r[:j])
80}
81
82// An errorString represents a runtime error described by a single string.
83type errorString string
84
85func (e errorString) RuntimeError() {}
86
87func (e errorString) Error() string {
88	return "runtime error: " + string(e)
89}
90
91// An errorCString represents a runtime error described by a single C string.
92// Not "type errorCString uintptr" because of http://golang.org/issue/7084.
93type errorCString struct{ cstr uintptr }
94
95func (e errorCString) RuntimeError() {}
96
97func (e errorCString) Error() string {
98	return "runtime error: " + gostringnocopy((*byte)(unsafe.Pointer(e.cstr)))
99}
100
101// For calling from C.
102func NewErrorCString(s uintptr, ret *interface{}) {
103	*ret = errorCString{s}
104}
105
106// plainError represents a runtime error described a string without
107// the prefix "runtime error: " after invoking errorString.Error().
108// See Issue #14965.
109type plainError string
110
111func (e plainError) RuntimeError() {}
112
113func (e plainError) Error() string {
114	return string(e)
115}
116
117type stringer interface {
118	String() string
119}
120
121func typestring(x interface{}) string {
122	e := efaceOf(&x)
123	return e._type.string()
124}
125
126// printany prints an argument passed to panic.
127// If panic is called with a value that has a String or Error method,
128// it has already been converted into a string by preprintpanics.
129func printany(i interface{}) {
130	switch v := i.(type) {
131	case nil:
132		print("nil")
133	case bool:
134		print(v)
135	case int:
136		print(v)
137	case int8:
138		print(v)
139	case int16:
140		print(v)
141	case int32:
142		print(v)
143	case int64:
144		print(v)
145	case uint:
146		print(v)
147	case uint8:
148		print(v)
149	case uint16:
150		print(v)
151	case uint32:
152		print(v)
153	case uint64:
154		print(v)
155	case uintptr:
156		print(v)
157	case float32:
158		print(v)
159	case float64:
160		print(v)
161	case complex64:
162		print(v)
163	case complex128:
164		print(v)
165	case string:
166		print(v)
167	default:
168		print("(", typestring(i), ") ", i)
169	}
170}
171