Commit 863ea6cf by Ian Lance Taylor

compiler: Permit converting between string and named []byte/[]rune.

From-SVN: r182291
parent 80fd8eba
...@@ -3322,7 +3322,7 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*, ...@@ -3322,7 +3322,7 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
mpfr_clear(imag); mpfr_clear(imag);
} }
if (type->is_slice_type() && type->named_type() == NULL) if (type->is_slice_type())
{ {
Type* element_type = type->array_type()->element_type()->forwarded(); Type* element_type = type->array_type()->element_type()->forwarded();
bool is_byte = element_type == Type::lookup_integer_type("uint8"); bool is_byte = element_type == Type::lookup_integer_type("uint8");
...@@ -3621,20 +3621,11 @@ Type_conversion_expression::do_get_tree(Translate_context* context) ...@@ -3621,20 +3621,11 @@ Type_conversion_expression::do_get_tree(Translate_context* context)
integer_type_node, integer_type_node,
fold_convert(integer_type_node, expr_tree)); fold_convert(integer_type_node, expr_tree));
} }
else if (type->is_string_type() else if (type->is_string_type() && expr_type->is_slice_type())
&& (expr_type->array_type() != NULL
|| (expr_type->points_to() != NULL
&& expr_type->points_to()->array_type() != NULL)))
{ {
Type* t = expr_type;
if (t->points_to() != NULL)
{
t = t->points_to();
expr_tree = build_fold_indirect_ref(expr_tree);
}
if (!DECL_P(expr_tree)) if (!DECL_P(expr_tree))
expr_tree = save_expr(expr_tree); expr_tree = save_expr(expr_tree);
Array_type* a = t->array_type(); Array_type* a = expr_type->array_type();
Type* e = a->element_type()->forwarded(); Type* e = a->element_type()->forwarded();
go_assert(e->integer_type() != NULL); go_assert(e->integer_type() != NULL);
tree valptr = fold_convert(const_ptr_type_node, tree valptr = fold_convert(const_ptr_type_node,
......
...@@ -662,7 +662,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) ...@@ -662,7 +662,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
{ {
if (rhs->integer_type() != NULL) if (rhs->integer_type() != NULL)
return true; return true;
if (rhs->is_slice_type() && rhs->named_type() == NULL) if (rhs->is_slice_type())
{ {
const Type* e = rhs->array_type()->element_type()->forwarded(); const Type* e = rhs->array_type()->element_type()->forwarded();
if (e->integer_type() != NULL if (e->integer_type() != NULL
...@@ -673,9 +673,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason) ...@@ -673,9 +673,7 @@ Type::are_convertible(const Type* lhs, const Type* rhs, std::string* reason)
} }
// A string may be converted to []byte or []int. // A string may be converted to []byte or []int.
if (rhs->is_string_type() if (rhs->is_string_type() && lhs->is_slice_type())
&& lhs->is_slice_type()
&& lhs->named_type() == NULL)
{ {
const Type* e = lhs->array_type()->element_type()->forwarded(); const Type* e = lhs->array_type()->element_type()->forwarded();
if (e->integer_type() != NULL if (e->integer_type() != NULL
......
...@@ -36,7 +36,7 @@ var good3 int = 1e9 ...@@ -36,7 +36,7 @@ var good3 int = 1e9
var good4 float64 = 1e20 var good4 float64 = 1e20
// explicit conversion of string is okay // explicit conversion of string is okay
var _ = []int("abc") var _ = []rune("abc")
var _ = []byte("abc") var _ = []byte("abc")
// implicit is not // implicit is not
...@@ -47,20 +47,20 @@ var _ []byte = "abc" // ERROR "cannot use|incompatible|invalid" ...@@ -47,20 +47,20 @@ var _ []byte = "abc" // ERROR "cannot use|incompatible|invalid"
type Tstring string type Tstring string
var ss Tstring = "abc" var ss Tstring = "abc"
var _ = []int(ss) var _ = []rune(ss)
var _ = []byte(ss) var _ = []byte(ss)
// implicit is still not // implicit is still not
var _ []int = ss // ERROR "cannot use|incompatible|invalid" var _ []rune = ss // ERROR "cannot use|incompatible|invalid"
var _ []byte = ss // ERROR "cannot use|incompatible|invalid" var _ []byte = ss // ERROR "cannot use|incompatible|invalid"
// named slice is not // named slice is now ok
type Tint []int type Trune []rune
type Tbyte []byte type Tbyte []byte
var _ = Tint("abc") // ERROR "convert|incompatible|invalid" var _ = Trune("abc") // ok
var _ = Tbyte("abc") // ERROR "convert|incompatible|invalid" var _ = Tbyte("abc") // ok
// implicit is still not // implicit is still not
var _ Tint = "abc" // ERROR "cannot use|incompatible|invalid" var _ Trune = "abc" // ERROR "cannot use|incompatible|invalid"
var _ Tbyte = "abc" // ERROR "cannot use|incompatible|invalid" var _ Tbyte = "abc" // ERROR "cannot use|incompatible|invalid"
...@@ -41,7 +41,6 @@ func main() { ...@@ -41,7 +41,6 @@ func main() {
asBool(i < j) // ERROR "cannot use.*type bool.*as type Bool" asBool(i < j) // ERROR "cannot use.*type bool.*as type Bool"
_, b = m[2] // ERROR "cannot .* bool.*type Bool" _, b = m[2] // ERROR "cannot .* bool.*type Bool"
m[2] = 1, b // ERROR "cannot use.*type Bool.*as type bool"
var inter interface{} var inter interface{}
_, b = inter.(Map) // ERROR "cannot .* bool.*type Bool" _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool"
...@@ -55,8 +54,8 @@ func main() { ...@@ -55,8 +54,8 @@ func main() {
_, bb := <-c _, bb := <-c
asBool(bb) // ERROR "cannot use.*type bool.*as type Bool" asBool(bb) // ERROR "cannot use.*type bool.*as type Bool"
_, b = <-c // ERROR "cannot .* bool.*type Bool" _, b = <-c // ERROR "cannot .* bool.*type Bool"
_ = b _ = b
asString(String(slice)) // ERROR "cannot .*type Slice.*type String" asString(String(slice)) // ok
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment