Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 40 additions & 36 deletions source/sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1511,11 +1511,15 @@ class sema
)
-> bool
{
std::vector<error_entry> devnull;
auto& errors = emit_errors ? this->errors : devnull;
const std::function emit_error = [this](source_position pos, std::string_view msg) {
errors.emplace_back(pos, msg);
};
const std::function skip_error = [](source_position, std::string_view){};

const auto handle_error = emit_errors ? emit_error : skip_error;
Comment on lines +1514 to +1519
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose to use two lambdas to make the emit_errors == false more explicitly no-op.


if (n.has_name("operator")) {
errors.emplace_back(
handle_error(
n.position(),
"the name 'operator' is incomplete - did you mean to write an overloaded operator name like 'operator*' or 'operator++'?"
);
Expand All @@ -1529,7 +1533,7 @@ class sema
&& !n.has_initializer()
)
{
errors.emplace_back(
handle_error(
n.position(),
"an object with a deduced type must have an = initializer"
);
Expand All @@ -1543,7 +1547,7 @@ class sema
&& !n.initializer->is_expression()
)
{
errors.emplace_back(
handle_error(
n.position(),
"an object initializer must be an expression"
);
Expand All @@ -1559,7 +1563,7 @@ class sema
)
)
{
errors.emplace_back(
handle_error(
n.position(),
"a namespace must be = initialized with a { } body containing declarations"
);
Expand All @@ -1573,7 +1577,7 @@ class sema
&& n.initializer->is_return()
)
{
errors.emplace_back(
handle_error(
n.position(),
"a function with a single-expression body doesn't need to say 'return' - either omit 'return' or write a full { }-enclosed function body"
);
Expand All @@ -1588,7 +1592,7 @@ class sema
&& !n.has_initializer()
)
{
errors.emplace_back(
handle_error(
n.position(),
"a function must have a body ('=' initializer), unless it is virtual (has a 'virtual this' parameter) or is defaultable (operator== or operator<=>)"
);
Expand All @@ -1601,7 +1605,7 @@ class sema
&& !n.parent_is_type()
)
{
errors.emplace_back(
handle_error(
n.position(),
"(temporary alpha limitation) a type must be in a namespace or type scope - function-local types are not yet supported"
);
Expand All @@ -1614,7 +1618,7 @@ class sema
&& n.has_wildcard_type()
)
{
errors.emplace_back(
handle_error(
n.position(),
"a type scope variable must have a declared type"
);
Expand All @@ -1632,7 +1636,7 @@ class sema
)
)
{
errors.emplace_back(
handle_error(
n.identifier->position(),
"'this' may only be declared as an ordinary function parameter or type-scope (base) object"
);
Expand All @@ -1646,14 +1650,14 @@ class sema

if (this_index >= 0) {
if (!n.parent_is_type()) {
errors.emplace_back(
handle_error(
n.position(),
"'this' must be the first parameter of a type-scope function"
);
return false;
}
if (this_index != 0) {
errors.emplace_back(
handle_error(
n.position(),
"'this' must be the first parameter"
);
Expand All @@ -1663,14 +1667,14 @@ class sema

if (that_index >= 0) {
if (!n.parent_is_type()) {
errors.emplace_back(
handle_error(
n.position(),
"'that' must be the second parameter of a type-scope function"
);
return false;
}
if (that_index != 1) {
errors.emplace_back(
handle_error(
n.position(),
"'that' must be the second parameter"
);
Expand All @@ -1685,7 +1689,7 @@ class sema
&& n.parent_is_namespace()
)
{
errors.emplace_back(
handle_error(
n.identifier->position(),
"namespace scope objects must have a concrete type, not a deduced type"
);
Expand All @@ -1699,7 +1703,7 @@ class sema
&& !n.is_object_alias()
)
{
errors.emplace_back(
handle_error(
n.identifier->position(),
"'_' (wildcard) may not be the name of a function or type - it may only be used as the name of an anonymous object, object alias, or namespace"
);
Expand All @@ -1712,7 +1716,7 @@ class sema
)
{
if (!n.is_object()) {
errors.emplace_back(
handle_error(
n.position(),
"a member named 'this' declares a base subobject, and must be followed by a base type name"
);
Expand All @@ -1724,7 +1728,7 @@ class sema
&& !n.is_default_access()
)
{
errors.emplace_back(
handle_error(
n.position(),
"a base type must be public (the default)"
);
Expand All @@ -1733,7 +1737,7 @@ class sema

if (n.has_wildcard_type())
{
errors.emplace_back(
handle_error(
n.position(),
"a base type must be a specific type, not a deduced type (omitted or '_'-wildcarded)"
);
Expand All @@ -1746,7 +1750,7 @@ class sema
&& !n.parent_is_type()
)
{
errors.emplace_back(
handle_error(
n.position(),
"an access-specifier is only allowed on a type-scope (member) declaration"
);
Expand All @@ -1761,7 +1765,7 @@ class sema
&& (*func->parameters)[0]->has_name("this")
);
if ((*func->parameters)[0]->is_polymorphic()) {
errors.emplace_back(
handle_error(
n.position(),
"a constructor may not be declared virtual, override, or final"
);
Expand All @@ -1777,7 +1781,7 @@ class sema
{
assert (n.identifier->get_token());
auto name = n.identifier->get_token()->to_string();
errors.emplace_back(
handle_error(
n.position(),
"(temporary alpha limitation) local functions like '" + name + ": (/*params*/) = {/*body*/}' are not currently supported - write a local variable initialized with an unnamed function like '" + name + " := :(/*params*/) = {/*body*/};' instead (add '=' and ';')"
);
Expand All @@ -1796,7 +1800,7 @@ class sema
)
)
{
errors.emplace_back(
handle_error(
n.position(),
"overloading '" + n.name()->to_string() + "' is not allowed"
);
Expand Down Expand Up @@ -1824,7 +1828,7 @@ class sema
)
)
{
errors.emplace_back(
handle_error(
n.position(),
n.name()->to_string() + " must have 'this' as the first parameter"
);
Expand Down Expand Up @@ -1861,7 +1865,7 @@ class sema
// ... and if it isn't that, then complain
else
{
errors.emplace_back(
handle_error(
params[0]->position(),
"'main' must be declared as 'main: ()' with zero parameters, or 'main: (args)' with one parameter named 'args' for which the type 'std::vector<std::string_view>' will be deduced"
);
Expand All @@ -1873,7 +1877,7 @@ class sema
{
if (!n.is_function())
{
errors.emplace_back(
handle_error(
n.position(),
"'operator=' must be a function"
);
Expand All @@ -1883,7 +1887,7 @@ class sema

if (func->has_declared_return_type())
{
errors.emplace_back(
handle_error(
func->parameters->parameters[0]->position(),
"'operator=' may not have a declared return type"
);
Expand All @@ -1892,7 +1896,7 @@ class sema

if (func->parameters->ssize() == 0)
{
errors.emplace_back(
handle_error(
n.position(),
"an operator= function must have a parameter"
);
Expand All @@ -1905,7 +1909,7 @@ class sema
&& (*func->parameters)[0]->pass != passing_style::move
)
{
errors.emplace_back(
handle_error(
n.position(),
"an operator= function's 'this' parameter must be inout, out, or move"
);
Expand All @@ -1919,7 +1923,7 @@ class sema
&& (*func->parameters)[1]->pass != passing_style::move
)
{
errors.emplace_back(
handle_error(
n.position(),
"an operator= function's 'that' parameter must be in or move"
);
Expand All @@ -1932,7 +1936,7 @@ class sema
&& (*func->parameters)[0]->pass == passing_style::move
)
{
errors.emplace_back(
handle_error(
n.position(),
"a destructor may not have other parameters besides 'this'"
);
Expand All @@ -1944,7 +1948,7 @@ class sema
{
if (decl->has_name("that"))
{
errors.emplace_back(
handle_error(
n.position(),
"'that' may not be used as a type scope name"
);
Expand All @@ -1957,7 +1961,7 @@ class sema
&& !n.has_bool_return_type()
)
{
errors.emplace_back(
handle_error(
n.position(),
n.name()->to_string() + " must return bool"
);
Expand All @@ -1973,7 +1977,7 @@ class sema
&& return_name.find("partial_ordering") == return_name.npos
)
{
errors.emplace_back(
handle_error(
n.position(),
"operator<=> must return std::strong_ordering, std::weak_ordering, or std::partial_ordering"
);
Expand All @@ -1990,7 +1994,7 @@ class sema
&& !stmt->is_using()
)
{
errors.emplace_back(
handle_error(
stmt->position(),
"a user-defined type body must contain only declarations or 'using' statements, not other code"
);
Expand Down