Repository: carbon-language/carbon-lang
File: toolchain/check/handle_function.cpp (C++)

Code before:
  if (!name_context.prev_inst_id().is_valid()) {
    // At interface scope, a function declaration introduces an associated
    // function.
    auto lookup_result_id = decl_id;
    if (parent_scope_inst && !name_context.has_qualifiers) {
      if (auto interface_scope =
              parent_scope_inst->TryAs<SemIR::InterfaceDecl>()) {
        lookup_result_id = BuildAssociatedEntity(
            context, interface_scope->interface_id, decl_id);
      }
    }

    context.decl_name_stack().AddName(name_context, lookup_result_id,
                                      introducer.modifier_set.GetAccessKind());
  }

  if (SemIR::IsEntryPoint(context.sem_ir(), function_decl.function_id)) {
    auto return_type_id = function_info.GetDeclaredReturnType(context.sem_ir());
    // TODO: Update this once valid signatures for the entry point are decided.
    if (function_info.implicit_param_patterns_id.is_valid() ||
        !function_info.param_patterns_id.is_valid() ||
        !context.inst_blocks().Get(function_info.param_patterns_id).empty() ||
        (return_type_id.is_valid() &&
         return_type_id != context.GetTupleType({}) &&
         // TODO: Decide on valid return types for `i32`. Perhaps we should have
         // an interface for this.
         return_type_id != MakeIntType(context, node_id, SemIR::IntKind::Signed,
                                       context.ints().Add(32)))) {
      CARBON_DIAGNOSTIC(InvalidMainRunSignature, Error,
                        "invalid signature for `Main.Run` function; expected "
                        "`fn ()` or `fn () -> i32`");
      context.emitter().Emit(node_id, InvalidMainRunSignature);
    }
  }

  if (!is_definition && context.IsImplFile() && !is_extern) {
    context.definitions_required().push_back(decl_id);
  }

  return {function_decl.function_id, decl_id};
}

auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
  BuildFunctionDecl(context, node_id, /*is_definition=*/false);
  context.decl_name_stack().PopScope();
  return true;
}

// Processes a function definition after a signature for which we have already
// built a function ID. This logic is shared between processing regular function
// definitions and delayed parsing of inline method definitions.

Review comment (suggestion):
```suggestion
         // TODO: Decide on valid return types for `Main.Run`. Perhaps we should
         // have an interface for this.
```

Feels like this meant `Run`

Code after:
  if (!name_context.prev_inst_id().is_valid()) {
    // At interface scope, a function declaration introduces an associated
    // function.
    auto lookup_result_id = decl_id;
    if (parent_scope_inst && !name_context.has_qualifiers) {
      if (auto interface_scope =
              parent_scope_inst->TryAs<SemIR::InterfaceDecl>()) {
        lookup_result_id = BuildAssociatedEntity(
            context, interface_scope->interface_id, decl_id);
      }
    }

    context.decl_name_stack().AddName(name_context, lookup_result_id,
                                      introducer.modifier_set.GetAccessKind());
  }

  if (SemIR::IsEntryPoint(context.sem_ir(), function_decl.function_id)) {
    auto return_type_id = function_info.GetDeclaredReturnType(context.sem_ir());
    // TODO: Update this once valid signatures for the entry point are decided.
    if (function_info.implicit_param_patterns_id.is_valid() ||
        !function_info.param_patterns_id.is_valid() ||
        !context.inst_blocks().Get(function_info.param_patterns_id).empty() ||
        (return_type_id.is_valid() &&
         return_type_id != context.GetTupleType({}) &&
         // TODO: Decide on valid return types for `Main.Run`. Perhaps we should
         // have an interface for this.
         return_type_id != MakeIntType(context, node_id, SemIR::IntKind::Signed,
                                       context.ints().Add(32)))) {
      CARBON_DIAGNOSTIC(InvalidMainRunSignature, Error,
                        "invalid signature for `Main.Run` function; expected "
                        "`fn ()` or `fn () -> i32`");
      context.emitter().Emit(node_id, InvalidMainRunSignature);
    }
  }

  if (!is_definition && context.IsImplFile() && !is_extern) {
    context.definitions_required().push_back(decl_id);
  }

  return {function_decl.function_id, decl_id};
}

auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
  BuildFunctionDecl(context, node_id, /*is_definition=*/false);
  context.decl_name_stack().PopScope();
  return true;
}

// Processes a function definition after a signature for which we have already
// built a function ID. This logic is shared between processing regular function
// definitions and delayed parsing of inline method definitions.