Don't incorrectly parse expression as type switch.
Improve error reporting of invalid type assertions. From-SVN: r167787
This commit is contained in:
parent
0c2e69043f
commit
05d556e837
3 changed files with 28 additions and 17 deletions
|
@ -11620,24 +11620,29 @@ Type_guard_expression::do_check_types(Gogo*)
|
|||
this->report_error(_("invalid unsafe.Pointer conversion"));
|
||||
}
|
||||
else if (expr_type->interface_type() == NULL)
|
||||
this->report_error(_("type assertion only valid for interface types"));
|
||||
{
|
||||
if (!expr_type->is_error_type() && !this->type_->is_error_type())
|
||||
this->report_error(_("type assertion only valid for interface types"));
|
||||
this->set_is_error();
|
||||
}
|
||||
else if (this->type_->interface_type() == NULL)
|
||||
{
|
||||
std::string reason;
|
||||
if (!expr_type->interface_type()->implements_interface(this->type_,
|
||||
&reason))
|
||||
{
|
||||
if (reason.empty())
|
||||
this->report_error(_("impossible type assertion: "
|
||||
"type does not implement interface"));
|
||||
else
|
||||
if (!this->type_->is_error_type())
|
||||
{
|
||||
error_at(this->location(),
|
||||
("impossible type assertion: "
|
||||
"type does not implement interface (%s)"),
|
||||
reason.c_str());
|
||||
this->set_is_error();
|
||||
if (reason.empty())
|
||||
this->report_error(_("impossible type assertion: "
|
||||
"type does not implement interface"));
|
||||
else
|
||||
error_at(this->location(),
|
||||
("impossible type assertion: "
|
||||
"type does not implement interface (%s)"),
|
||||
reason.c_str());
|
||||
}
|
||||
this->set_is_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2647,12 +2647,18 @@ Parse::selector(Expression* left, bool* is_type_switch)
|
|||
{
|
||||
this->advance_token();
|
||||
Type* type = NULL;
|
||||
if (is_type_switch == NULL
|
||||
|| !this->peek_token()->is_keyword(KEYWORD_TYPE))
|
||||
if (!this->peek_token()->is_keyword(KEYWORD_TYPE))
|
||||
type = this->type();
|
||||
else
|
||||
{
|
||||
*is_type_switch = true;
|
||||
if (is_type_switch != NULL)
|
||||
*is_type_switch = true;
|
||||
else
|
||||
{
|
||||
error_at(this->location(),
|
||||
"use of %<.(type)%> outside type switch");
|
||||
type = Type::make_error_type();
|
||||
}
|
||||
this->advance_token();
|
||||
}
|
||||
if (!this->peek_token()->is_op(OPERATOR_RPAREN))
|
||||
|
@ -2866,7 +2872,7 @@ Parse::expression(Precedence precedence, bool may_be_sink,
|
|||
left = this->verify_not_sink(left);
|
||||
Expression* right = this->expression(right_precedence, false,
|
||||
may_be_composite_lit,
|
||||
is_type_switch);
|
||||
NULL);
|
||||
if (op == OPERATOR_CHANOP)
|
||||
left = Expression::make_send(left, right, binop_location);
|
||||
else
|
||||
|
@ -2959,8 +2965,7 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
|
|||
return Expression::make_type(this->type(), location);
|
||||
}
|
||||
|
||||
Expression* expr = this->unary_expr(false, may_be_composite_lit,
|
||||
is_type_switch);
|
||||
Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL);
|
||||
if (expr->is_error_expression())
|
||||
;
|
||||
else if (op == OPERATOR_MULT && expr->is_type_expression())
|
||||
|
|
|
@ -1296,7 +1296,8 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Block* enclosing)
|
|||
Type* expr_type = this->expr_->type();
|
||||
if (expr_type->interface_type() == NULL)
|
||||
{
|
||||
this->report_error(_("type assertion only valid for interface types"));
|
||||
if (!expr_type->is_error_type() && !this->type_->is_error_type())
|
||||
this->report_error(_("type assertion only valid for interface types"));
|
||||
return Statement::make_error_statement(loc);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue