Parse parameters in name qualifiers. (#3988)

Parse the name of a declaration as a sequence of `NameQualifier`s --
which have a name, possibly parameters, and a trailing period --
followed by a name and possibly parameters. This prepares us for parsing
declarations of members of generic classes and similar cases, but
actually supporting such member redeclarations is left to a future
change.

We previously required functions to have parameters, but no longer do,
following the direction of #3848. Cases like namespaces that can't
actually have parameters are now diagnosed in check instead of in parse.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2024-05-29 00:47:29 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 582b2c04dd
commit 28170c7867
41 changed files with 807 additions and 371 deletions
+14 -8
View File
@@ -211,8 +211,12 @@ static auto BuildFunctionDecl(Context& context,
return_slot = SemIR::Function::ReturnSlot::Absent;
}
SemIR::InstBlockId param_refs_id =
context.node_stack().Pop<Parse::NodeKind::TuplePattern>();
auto param_refs_id =
context.node_stack().PopIf<Parse::NodeKind::TuplePattern>();
if (!param_refs_id) {
context.TODO(node_id, "function with positional parameters");
param_refs_id = SemIR::InstBlockId::Empty;
}
// TODO: Use Invalid rather than Empty if there was no implicit parameter
// list.
SemIR::InstBlockId implicit_param_refs_id =
@@ -253,7 +257,7 @@ static auto BuildFunctionDecl(Context& context,
.enclosing_scope_id = name_context.enclosing_scope_id_for_new_inst(),
.decl_id = context.AddPlaceholderInst({node_id, function_decl}),
.implicit_param_refs_id = implicit_param_refs_id,
.param_refs_id = param_refs_id,
.param_refs_id = *param_refs_id,
.return_type_id = return_type_id,
.return_storage_id = return_storage_id,
.is_extern = is_extern,
@@ -297,12 +301,14 @@ static auto BuildFunctionDecl(Context& context,
if (SemIR::IsEntryPoint(context.sem_ir(), function_decl.function_id)) {
// TODO: Update this once valid signatures for the entry point are decided.
if (!context.inst_blocks().Get(implicit_param_refs_id).empty() ||
!context.inst_blocks().Get(param_refs_id).empty() ||
(return_type_id.is_valid() &&
return_type_id !=
if (!context.inst_blocks()
.Get(function_info.implicit_param_refs_id)
.empty() ||
!context.inst_blocks().Get(function_info.param_refs_id).empty() ||
(function_info.return_type_id.is_valid() &&
function_info.return_type_id !=
context.GetBuiltinType(SemIR::BuiltinKind::IntType) &&
return_type_id != context.GetTupleType({}))) {
function_info.return_type_id != context.GetTupleType({}))) {
CARBON_DIAGNOSTIC(InvalidMainRunSignature, Error,
"Invalid signature for `Main.Run` function. Expected "
"`fn ()` or `fn () -> i32`.");