Commit 05d556e8 by Ian Lance Taylor

Don't incorrectly parse expression as type switch.

Improve error reporting of invalid type assertions.

From-SVN: r167787
parent 0c2e6904
...@@ -11620,24 +11620,29 @@ Type_guard_expression::do_check_types(Gogo*) ...@@ -11620,24 +11620,29 @@ Type_guard_expression::do_check_types(Gogo*)
this->report_error(_("invalid unsafe.Pointer conversion")); this->report_error(_("invalid unsafe.Pointer conversion"));
} }
else if (expr_type->interface_type() == NULL) else if (expr_type->interface_type() == NULL)
{
if (!expr_type->is_error_type() && !this->type_->is_error_type())
this->report_error(_("type assertion only valid for interface types")); this->report_error(_("type assertion only valid for interface types"));
this->set_is_error();
}
else if (this->type_->interface_type() == NULL) else if (this->type_->interface_type() == NULL)
{ {
std::string reason; std::string reason;
if (!expr_type->interface_type()->implements_interface(this->type_, if (!expr_type->interface_type()->implements_interface(this->type_,
&reason)) &reason))
{ {
if (!this->type_->is_error_type())
{
if (reason.empty()) if (reason.empty())
this->report_error(_("impossible type assertion: " this->report_error(_("impossible type assertion: "
"type does not implement interface")); "type does not implement interface"));
else else
{
error_at(this->location(), error_at(this->location(),
("impossible type assertion: " ("impossible type assertion: "
"type does not implement interface (%s)"), "type does not implement interface (%s)"),
reason.c_str()); reason.c_str());
this->set_is_error();
} }
this->set_is_error();
} }
} }
} }
......
...@@ -2647,12 +2647,18 @@ Parse::selector(Expression* left, bool* is_type_switch) ...@@ -2647,12 +2647,18 @@ Parse::selector(Expression* left, bool* is_type_switch)
{ {
this->advance_token(); this->advance_token();
Type* type = NULL; Type* type = NULL;
if (is_type_switch == NULL if (!this->peek_token()->is_keyword(KEYWORD_TYPE))
|| !this->peek_token()->is_keyword(KEYWORD_TYPE))
type = this->type(); type = this->type();
else else
{ {
if (is_type_switch != NULL)
*is_type_switch = true; *is_type_switch = true;
else
{
error_at(this->location(),
"use of %<.(type)%> outside type switch");
type = Type::make_error_type();
}
this->advance_token(); this->advance_token();
} }
if (!this->peek_token()->is_op(OPERATOR_RPAREN)) if (!this->peek_token()->is_op(OPERATOR_RPAREN))
...@@ -2866,7 +2872,7 @@ Parse::expression(Precedence precedence, bool may_be_sink, ...@@ -2866,7 +2872,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
left = this->verify_not_sink(left); left = this->verify_not_sink(left);
Expression* right = this->expression(right_precedence, false, Expression* right = this->expression(right_precedence, false,
may_be_composite_lit, may_be_composite_lit,
is_type_switch); NULL);
if (op == OPERATOR_CHANOP) if (op == OPERATOR_CHANOP)
left = Expression::make_send(left, right, binop_location); left = Expression::make_send(left, right, binop_location);
else else
...@@ -2959,8 +2965,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit, ...@@ -2959,8 +2965,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
return Expression::make_type(this->type(), location); return Expression::make_type(this->type(), location);
} }
Expression* expr = this->unary_expr(false, may_be_composite_lit, Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL);
is_type_switch);
if (expr->is_error_expression()) if (expr->is_error_expression())
; ;
else if (op == OPERATOR_MULT && expr->is_type_expression()) else if (op == OPERATOR_MULT && expr->is_type_expression())
......
...@@ -1296,6 +1296,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing) ...@@ -1296,6 +1296,7 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing)
Type* expr_type = this->expr_->type(); Type* expr_type = this->expr_->type();
if (expr_type->interface_type() == NULL) if (expr_type->interface_type() == NULL)
{ {
if (!expr_type->is_error_type() && !this->type_->is_error_type())
this->report_error(_("type assertion only valid for interface types")); this->report_error(_("type assertion only valid for interface types"));
return Statement::make_error_statement(loc); return Statement::make_error_statement(loc);
} }
......
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