Skip to content

Commit a59167c

Browse files
compiler: finalize methods for type aliases of struct types
Previously we would finalize the methods of the alias type itself, but since its a type alias we really need to finalize the methods of the aliased type. Also, handle method expressions of unnamed struct types. Test case is https://golang.org/cl/251168. Fixes golang/go#38125 Change-Id: I84c98883ae8641c5fa2b6c5209bf5ef9bb38e57b Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/251279 Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
1 parent 6f30979 commit a59167c

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

go/expressions.cc

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14529,38 +14529,48 @@ Selector_expression::lower_method_expression(Gogo* gogo)
1452914529
is_pointer = true;
1453014530
type = type->points_to();
1453114531
}
14532-
Named_type* nt = type->named_type();
14533-
if (nt == NULL)
14534-
{
14535-
go_error_at(location,
14536-
("method expression requires named type or "
14537-
"pointer to named type"));
14538-
return Expression::make_error(location);
14539-
}
1454014532

14533+
Named_type* nt = type->named_type();
14534+
Struct_type* st = type->struct_type();
1454114535
bool is_ambiguous;
14542-
Method* method = nt->method_function(name, &is_ambiguous);
14536+
Method* method = NULL;
14537+
if (nt != NULL)
14538+
method = nt->method_function(name, &is_ambiguous);
14539+
else if (st != NULL)
14540+
method = st->method_function(name, &is_ambiguous);
1454314541
const Typed_identifier* imethod = NULL;
1454414542
if (method == NULL && !is_pointer)
1454514543
{
14546-
Interface_type* it = nt->interface_type();
14544+
Interface_type* it = type->interface_type();
1454714545
if (it != NULL)
1454814546
imethod = it->find_method(name);
1454914547
}
1455014548

1455114549
if ((method == NULL && imethod == NULL)
1455214550
|| (left_type->named_type() != NULL && left_type->points_to() != NULL))
1455314551
{
14554-
if (!is_ambiguous)
14555-
go_error_at(location, "type %<%s%s%> has no method %<%s%>",
14556-
is_pointer ? "*" : "",
14557-
nt->message_name().c_str(),
14558-
Gogo::message_name(name).c_str());
14552+
if (nt != NULL)
14553+
{
14554+
if (!is_ambiguous)
14555+
go_error_at(location, "type %<%s%s%> has no method %<%s%>",
14556+
is_pointer ? "*" : "",
14557+
nt->message_name().c_str(),
14558+
Gogo::message_name(name).c_str());
14559+
else
14560+
go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
14561+
Gogo::message_name(name).c_str(),
14562+
is_pointer ? "*" : "",
14563+
nt->message_name().c_str());
14564+
}
1455914565
else
14560-
go_error_at(location, "method %<%s%s%> is ambiguous in type %<%s%>",
14561-
Gogo::message_name(name).c_str(),
14562-
is_pointer ? "*" : "",
14563-
nt->message_name().c_str());
14566+
{
14567+
if (!is_ambiguous)
14568+
go_error_at(location, "type has no method %<%s%>",
14569+
Gogo::message_name(name).c_str());
14570+
else
14571+
go_error_at(location, "method %<%s%> is ambiguous",
14572+
Gogo::message_name(name).c_str());
14573+
}
1456414574
return Expression::make_error(location);
1456514575
}
1456614576

@@ -14657,7 +14667,7 @@ Selector_expression::lower_method_expression(Gogo* gogo)
1465714667
Expression* ve = Expression::make_var_reference(vno, location);
1465814668
Expression* bm;
1465914669
if (method != NULL)
14660-
bm = Type::bind_field_or_method(gogo, nt, ve, name, location);
14670+
bm = Type::bind_field_or_method(gogo, type, ve, name, location);
1466114671
else
1466214672
bm = Expression::make_interface_field_reference(ve, name, location);
1466314673

go/gogo.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,10 @@ Finalize_methods::type(Type* t)
35083508
case Type::TYPE_NAMED:
35093509
{
35103510
Named_type* nt = t->named_type();
3511+
3512+
if (nt->is_alias())
3513+
return TRAVERSE_CONTINUE;
3514+
35113515
Type* rt = nt->real_type();
35123516
if (rt->classification() != Type::TYPE_STRUCT)
35133517
{

0 commit comments

Comments
 (0)