if x.mode == constant && isConstType(typ) {
// constant conversion
- // TODO(gri) implement this
+ typ := underlying(typ).(*Basic)
+ // For now just implement string(x) where x is an integer,
+ // as a temporary work-around for issue 4982, which is a
+ // common issue.
+ if typ.Kind == String {
+ switch {
+ case x.isInteger(check.ctxt):
+ codepoint, ok := x.val.(int64)
+ if !ok {
+ // absolute value too large (or unknown) for conversion;
+ // same as converting any other out-of-range value - let
+ // string(codepoint) do the work
+ codepoint = -1
+ }
+ x.val = string(codepoint)
+ case isString(x.typ):
+ // nothing to do
+ default:
+ goto ErrorMsg
+ }
+ }
+ // TODO(gri) verify the remaining conversions.
} else {
// non-constant conversion
if !x.isConvertible(check.ctxt, typ) {
- check.invalidOp(conv.Pos(), "cannot convert %s to %s", x, typ)
- goto Error
+ goto ErrorMsg
}
x.mode = value
}
x.typ = typ
return
+ErrorMsg:
+ check.invalidOp(conv.Pos(), "cannot convert %s to %s", x, typ)
Error:
x.mode = invalid
+ x.expr = conv
}
func (x *operand) isConvertible(ctxt *Context, T Type) bool {
}
// isInteger reports whether x is a (typed or untyped) integer value.
+// TODO(gri) remove ctxt argument - it is not required for UntypedInt.
func (x *operand) isInteger(ctxt *Context) bool {
return x.mode == invalid ||
isInteger(x.typ) ||
// argument count
var (
- _v0 = int /* ERROR "one argument" */ ()
- _v1 = int /* ERROR "one argument" */ (1, 2)
+ _ = int /* ERROR "one argument" */ ()
+ _ = int /* ERROR "one argument" */ (1, 2)
)
-//
+func string_conversions() {
+ const A = string(65)
+ assert(A == "A")
+ const E = string(-1)
+ assert(E == "\uFFFD")
+ assert(E == string(1234567890))
+
+ type myint int
+ assert(A == string(myint(65)))
+
+ type mystring string
+ const _ mystring = mystring("foo")
+
+ const _ = string /* ERROR "cannot convert" */ (true)
+ const _ = string /* ERROR "cannot convert" */ (1.2)
+ const _ = string /* ERROR "cannot convert" */ (nil)
+}
+
+//
var (
- _v2 = int8(0)
+ _ = int8(0)
)
\ No newline at end of file