This patch to the Go frontend fixes using a package name as a key in a struct composite literal. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r c266c495ca06 go/expressions.cc --- a/go/expressions.cc Mon Aug 29 15:04:11 2011 -0700 +++ b/go/expressions.cc Fri Sep 09 21:08:58 2011 -0700 @@ -1436,7 +1436,6 @@ Expression* Expression::make_unknown_reference(Named_object* no, source_location location) { - go_assert(no->resolve()->is_unknown()); return new Unknown_expression(no, location); } diff -r c266c495ca06 go/parse.cc --- a/go/parse.cc Mon Aug 29 15:04:11 2011 -0700 +++ b/go/parse.cc Fri Sep 09 21:08:58 2011 -0700 @@ -2445,7 +2445,9 @@ // LiteralValue = "{" [ ElementList [ "," ] ] "}" . // ElementList = Element { "," Element } . // Element = [ Key ":" ] Value . -// Key = Expression . +// Key = FieldName | ElementIndex . +// FieldName = identifier . +// ElementIndex = Expression . // Value = Expression | LiteralValue . // We have already seen the type if there is one, and we are now @@ -2478,7 +2480,33 @@ const Token* token = this->peek_token(); - if (!token->is_op(OPERATOR_LCURLY)) + if (token->is_identifier()) + { + std::string identifier = token->identifier(); + bool is_exported = token->is_identifier_exported(); + source_location location = token->location(); + + if (this->advance_token()->is_op(OPERATOR_COLON)) + { + // This may be a field name. We don't know for sure--it + // could also be an expression for an array index. We + // don't want to parse it as an expression because may + // trigger various errors, e.g., if this identifier + // happens to be the name of a package. + Gogo* gogo = this->gogo_; + val = this->id_to_expression(gogo->pack_hidden_name(identifier, + is_exported), + location); + } + else + { + this->unget_token(Token::make_identifier_token(identifier, + is_exported, + location)); + val = this->expression(PRECEDENCE_NORMAL, false, true, NULL); + } + } + else if (!token->is_op(OPERATOR_LCURLY)) val = this->expression(PRECEDENCE_NORMAL, false, true, NULL); else { @@ -2922,6 +2950,12 @@ return Expression::make_func_reference(named_object, NULL, location); case Named_object::NAMED_OBJECT_UNKNOWN: return Expression::make_unknown_reference(named_object, location); + case Named_object::NAMED_OBJECT_PACKAGE: + case Named_object::NAMED_OBJECT_TYPE: + case Named_object::NAMED_OBJECT_TYPE_DECLARATION: + // These cases can arise for a field name in a composite + // literal. + return Expression::make_unknown_reference(named_object, location); default: error_at(this->location(), "unexpected type of identifier"); return Expression::make_error(location);