@@ -122,23 +122,61 @@ ASTValidation::visit (AST::Function &function)
function.get_self_param ()->get_locus (),
"%<self%> parameter is only allowed in associated functions");
- if (!function.has_body ())
+ if (function.is_external ())
{
- if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+ if (function.has_body ())
+ rust_error_at (function.get_locus (), "cannot have a body");
+
+ auto ¶ms = function.get_function_params ();
+
+ if (params.size () == 1 && function.is_variadic ())
rust_error_at (function.get_locus (),
- "associated function in %<impl%> without body");
- else if (context.back () != Context::TRAIT)
- rust_error_at (function.get_locus (), "free function without a body");
+ "C-variadic function must be declared with at least one "
+ "named argument");
+
+ for (auto it = params.begin (); it != params.end (); it++)
+ {
+ if (it->get ()->is_variadic () && it + 1 != params.end ())
+ rust_error_at (
+ it->get ()->get_locus (),
+ "%<...%> must be the last argument of a C-variadic function");
+
+ // if functional parameter
+ if (!it->get ()->is_self () && !it->get ()->is_variadic ())
+ {
+ auto param = static_cast<AST::FunctionParam *> (it->get ());
+ auto kind = param->get_pattern ()->get_pattern_kind ();
+
+ if (kind != AST::Pattern::Kind::Identifier
+ && kind != AST::Pattern::Kind::Wildcard)
+ rust_error_at (it->get ()->get_locus (), ErrorCode::E0130,
+ "pattern not allowed in foreign function");
+ }
+ }
}
- auto &function_params = function.get_function_params ();
- for (auto it = function_params.begin (); it != function_params.end (); it++)
+ else
{
- if (it->get ()->is_variadic ())
- rust_error_at (it->get ()->get_locus (),
- "only foreign or %<unsafe extern \"C\"%> functions may "
- "be C-variadic");
+ if (!function.has_body ())
+ {
+ if (context.back () == Context::INHERENT_IMPL
+ || context.back () == Context::TRAIT_IMPL)
+ rust_error_at (function.get_locus (),
+ "associated function in %<impl%> without body");
+ else if (context.back () != Context::TRAIT)
+ rust_error_at (function.get_locus (),
+ "free function without a body");
+ }
+ auto &function_params = function.get_function_params ();
+ for (auto it = function_params.begin (); it != function_params.end ();
+ it++)
+ {
+ if (it->get ()->is_variadic ())
+ rust_error_at (
+ it->get ()->get_locus (),
+ "only foreign or %<unsafe extern \"C\"%> functions may "
+ "be C-variadic");
+ }
}
AST::ContextualASTVisitor::visit (function);
@@ -2908,7 +2908,8 @@ Parser<ManagedTokenSource>::parse_use_tree ()
template <typename ManagedTokenSource>
std::unique_ptr<AST::Function>
Parser<ManagedTokenSource>::parse_function (AST::Visibility vis,
- AST::AttrVec outer_attrs)
+ AST::AttrVec outer_attrs,
+ bool is_external)
{
location_t locus = lexer.peek_token ()->get_locus ();
// Get qualifiers for function if they exist
@@ -2992,7 +2993,7 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis,
std::move (generic_params), std::move (function_params),
std::move (return_type), std::move (where_clause),
std::move (body), std::move (vis),
- std::move (outer_attrs), locus));
+ std::move (outer_attrs), locus, false, is_external));
}
// Parses function or method qualifiers (i.e. const, unsafe, and extern).
@@ -6166,6 +6167,7 @@ Parser<ManagedTokenSource>::parse_external_item ()
case FN_KW:
return parse_external_function_item (std::move (vis),
std::move (outer_attrs));
+
case TYPE:
return parse_external_type_item (std::move (vis),
std::move (outer_attrs));
@@ -10474,8 +10476,7 @@ Parser<ManagedTokenSource>::parse_pattern ()
{
lexer.skip_token ();
alts.push_back (parse_pattern_no_alt ());
- }
- while (lexer.peek_token ()->get_id () == PIPE);
+ } while (lexer.peek_token ()->get_id () == PIPE);
/* alternates */
return std::unique_ptr<AST::Pattern> (
@@ -253,7 +253,8 @@ private:
parse_use_decl (AST::Visibility vis, AST::AttrVec outer_attrs);
std::unique_ptr<AST::UseTree> parse_use_tree ();
std::unique_ptr<AST::Function> parse_function (AST::Visibility vis,
- AST::AttrVec outer_attrs);
+ AST::AttrVec outer_attrs,
+ bool is_external = false);
AST::FunctionQualifiers parse_function_qualifiers ();
std::vector<std::unique_ptr<AST::GenericParam>>
parse_generic_params_in_angles ();