Skip to content

Commit

Permalink
Support _ unnamed type parameters - closes #812
Browse files Browse the repository at this point in the history
Also require an `operator=` second parameter of the same type to be named `that` - see #475 discussion thread
  • Loading branch information
hsutter committed Nov 10, 2023
1 parent 61550a5 commit 76c2941
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ auto add_42_to_subrange(auto& rng, cpp2::in<int> start, cpp2::in<int> end) -> vo
auto count {0};
for (

auto& i : rng ) { do
auto& i : rng ) { do
if ([_0 = start, _1 = count, _2 = end]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less_eq(_1,_2); }()) {
i += 42;
} while (false); ++count; }
Expand Down
8 changes: 4 additions & 4 deletions regression-tests/test-results/mixed-forwarding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ struct X {
};

#line 11 "mixed-forwarding.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void;
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void;

auto use([[maybe_unused]] auto const& param1) -> void;
auto use([[maybe_unused]] auto const& unnamed_param_1) -> void;

// invoking each of these with an rvalue std::pair argument ...
auto apply_implicit_forward(auto&& t) -> void
Expand All @@ -46,9 +46,9 @@ CPP2_REQUIRES (std::is_same_v<CPP2_TYPEOF(t), std::pair<X,X>>)


#line 11 "mixed-forwarding.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void{}
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void{}

auto use([[maybe_unused]] auto const& param1) -> void{}
auto use([[maybe_unused]] auto const& unnamed_param_1) -> void{}

#line 16 "mixed-forwarding.cpp2"
auto apply_implicit_forward(auto&& t) -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
#include <ctime>

#line 6 "mixed-parameter-passing-with-forward.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void;
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void;

auto parameter_styles(
[[maybe_unused]] cpp2::in<std::string> param1, // "in" is default
[[maybe_unused]] cpp2::in<std::string> unnamed_param_1, // "in" is default
std::string b,
[[maybe_unused]] std::string& param3,
[[maybe_unused]] std::string& unnamed_param_3,
std::string&& d,
auto&& e
) -> void
Expand All @@ -36,12 +36,12 @@ CPP2_REQUIRES (std::is_same_v<CPP2_TYPEOF(e), std::string>)


#line 6 "mixed-parameter-passing-with-forward.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void{}
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void{}

auto parameter_styles(
[[maybe_unused]] cpp2::in<std::string> param1,
[[maybe_unused]] cpp2::in<std::string> unnamed_param_1,
std::string b,
[[maybe_unused]] std::string& param3,
[[maybe_unused]] std::string& unnamed_param_3,
std::string&& d,
auto&& e
) -> void
Expand Down
12 changes: 6 additions & 6 deletions regression-tests/test-results/mixed-parameter-passing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
#include <ctime>

#line 6 "mixed-parameter-passing.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void;
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void;

auto parameter_styles(
[[maybe_unused]] cpp2::in<std::string> param1, // "in" is default
[[maybe_unused]] cpp2::in<std::string> unnamed_param_1, // "in" is default
std::string b,
[[maybe_unused]] std::string& param3,
[[maybe_unused]] std::string& unnamed_param_3,
std::string&& d
) -> void;

Expand All @@ -32,12 +32,12 @@ auto parameter_styles(


#line 6 "mixed-parameter-passing.cpp2"
auto copy_from([[maybe_unused]] auto param1) -> void{}
auto copy_from([[maybe_unused]] auto unnamed_param_1) -> void{}

auto parameter_styles(
[[maybe_unused]] cpp2::in<std::string> param1,
[[maybe_unused]] cpp2::in<std::string> unnamed_param_1,
std::string b,
[[maybe_unused]] std::string& param3,
[[maybe_unused]] std::string& unnamed_param_3,
std::string&& d
) -> void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


#line 2 "mixed-postfix-expression-custom-formatting.cpp2"
auto call([[maybe_unused]] auto const& param1, [[maybe_unused]] auto const& param2, [[maybe_unused]] auto const& param3, [[maybe_unused]] auto const& param4, [[maybe_unused]] auto const& param5) -> void;
auto call([[maybe_unused]] auto const& unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3, [[maybe_unused]] auto const& unnamed_param_4, [[maybe_unused]] auto const& unnamed_param_5) -> void;

[[nodiscard]] auto test(auto const& a) -> std::string;

Expand All @@ -24,7 +24,7 @@ auto call([[maybe_unused]] auto const& param1, [[maybe_unused]] auto const& para


#line 2 "mixed-postfix-expression-custom-formatting.cpp2"
auto call([[maybe_unused]] auto const& param1, [[maybe_unused]] auto const& param2, [[maybe_unused]] auto const& param3, [[maybe_unused]] auto const& param4, [[maybe_unused]] auto const& param5) -> void{}
auto call([[maybe_unused]] auto const& unnamed_param_1, [[maybe_unused]] auto const& unnamed_param_2, [[maybe_unused]] auto const& unnamed_param_3, [[maybe_unused]] auto const& unnamed_param_4, [[maybe_unused]] auto const& unnamed_param_5) -> void{}

[[nodiscard]] auto test(auto const& a) -> std::string{
return call(a,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class Base {

#line 3 "pure2-bugfix-for-memberwise-base-assignment.cpp2"
public: auto operator=([[maybe_unused]] Base&& that) noexcept -> Base& ;
public: Base([[maybe_unused]] auto const& param2);
public: Base([[maybe_unused]] auto const& unnamed_param_2);
#line 4 "pure2-bugfix-for-memberwise-base-assignment.cpp2"
public: auto operator=([[maybe_unused]] auto const& param2) -> Base& ;
public: auto operator=([[maybe_unused]] auto const& unnamed_param_2) -> Base& ;
};

class Derived: public Base {
Expand Down Expand Up @@ -60,9 +60,9 @@ auto main() -> int;
return *this;
#line 3 "pure2-bugfix-for-memberwise-base-assignment.cpp2"
}
Base::Base([[maybe_unused]] auto const& param2) { std::cout << "(implicit out this, _)\n"; }
Base::Base([[maybe_unused]] auto const& unnamed_param_2) { std::cout << "(implicit out this, _)\n"; }
#line 4 "pure2-bugfix-for-memberwise-base-assignment.cpp2"
auto Base::operator=([[maybe_unused]] auto const& param2) -> Base& { std::cout << "(implicit out this, _)\n";
auto Base::operator=([[maybe_unused]] auto const& unnamed_param_2) -> Base& { std::cout << "(implicit out this, _)\n";
return *this;
#line 4 "pure2-bugfix-for-memberwise-base-assignment.cpp2"
}
Expand Down
10 changes: 5 additions & 5 deletions regression-tests/test-results/pure2-print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ CPP2_REQUIRES_ (true)


#line 54 "pure2-print.cpp2"
public: template<typename T> [[nodiscard]] auto values([[maybe_unused]] T const& param2) const& -> values_ret;
public: template<typename T> [[nodiscard]] auto values([[maybe_unused]] T const& unnamed_param_2) const& -> values_ret;


#line 59 "pure2-print.cpp2"
public: explicit mytype();

public: mytype([[maybe_unused]] mytype const& that);

public: mytype([[maybe_unused]] cpp2::in<int> param2);
public: mytype([[maybe_unused]] cpp2::in<int> unnamed_param_2);

public: static auto variadic(auto const& ...x) -> void
CPP2_REQUIRES_ ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...))
Expand Down Expand Up @@ -133,7 +133,7 @@ requires (true)

do {} while ( CPP2_UFCS_0(empty, s) && [&]{ b() ; return true; }() );

for ( [[maybe_unused]] auto const& param1 : m ) {
for ( [[maybe_unused]] auto const& unnamed_param_1 : m ) {
#line 43 "pure2-print.cpp2"
{ do {goto CONTINUE_43_13; } while (false); c(); } CPP2_CONTINUE_BREAK(43_13) }

Expand All @@ -147,7 +147,7 @@ requires (true)
return [_0 = (s + cpp2::assert_in_bounds(m, 0))]() -> std::string { return _0; }();
}

template<typename T> [[nodiscard]] auto outer::mytype::values([[maybe_unused]] T const& param2) const& -> values_ret{
template<typename T> [[nodiscard]] auto outer::mytype::values([[maybe_unused]] T const& unnamed_param_2) const& -> values_ret{
cpp2::deferred_init<int> offset;
cpp2::deferred_init<std::string> name;
#line 55 "pure2-print.cpp2"
Expand All @@ -159,7 +159,7 @@ requires (true)

outer::mytype::mytype([[maybe_unused]] mytype const& that){}

outer::mytype::mytype([[maybe_unused]] cpp2::in<int> param2){}
outer::mytype::mytype([[maybe_unused]] cpp2::in<int> unnamed_param_2){}

auto outer::mytype::variadic(auto const& ...x) -> void
requires ((std::is_convertible_v<CPP2_TYPEOF(x), int> && ...))
Expand Down
8 changes: 4 additions & 4 deletions regression-tests/test-results/pure2-types-down-upcast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class B: public A {
#line 11 "pure2-types-down-upcast.cpp2"
};

auto func_mut(A& a) -> void;
auto func_mut(B& b) -> void;
auto func_mut(A& a) -> void;
auto func_mut(B& b) -> void;
auto func_const(cpp2::in<A> a) -> void;
auto func_const(cpp2::in<B> b) -> void;

Expand Down Expand Up @@ -69,8 +69,8 @@ auto test_down() -> void;
auto A::mut_foo() & -> void{std::cout << "foo \n"; }

#line 13 "pure2-types-down-upcast.cpp2"
auto func_mut(A& a) -> void {std::cout << "Call A mut: " + cpp2::to_string(a.i) << std::endl;}
auto func_mut(B& b) -> void {std::cout << "Call B mut: " + cpp2::to_string(b.d) << std::endl;}
auto func_mut(A& a) -> void {std::cout << "Call A mut: " + cpp2::to_string(a.i) << std::endl;}
auto func_mut(B& b) -> void {std::cout << "Call B mut: " + cpp2::to_string(b.d) << std::endl;}
auto func_const(cpp2::in<A> a) -> void{std::cout << "Call A const: " + cpp2::to_string(a.i) << std::endl;}
auto func_const(cpp2::in<B> b) -> void{std::cout << "Call B const: " + cpp2::to_string(b.d) << std::endl;}

Expand Down
4 changes: 2 additions & 2 deletions regression-tests/test-results/pure2-types-inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public: virtual ~Human() noexcept;

namespace N {
template<int I> class Machine {
public: explicit Machine([[maybe_unused]] cpp2::in<std::string> param2);
public: explicit Machine([[maybe_unused]] cpp2::in<std::string> unnamed_param_2);
public: virtual auto work() const -> void = 0;

public: virtual ~Machine() noexcept;
Expand Down Expand Up @@ -97,7 +97,7 @@ auto main() -> int;
#line 6 "pure2-types-inheritance.cpp2"
namespace N {

template <int I> Machine<I>::Machine([[maybe_unused]] cpp2::in<std::string> param2){}
template <int I> Machine<I>::Machine([[maybe_unused]] cpp2::in<std::string> unnamed_param_2){}

template <int I> Machine<I>::~Machine() noexcept{}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


#line 24 "pure2-ufcs-member-access-and-chaining.cpp2"
auto no_return([[maybe_unused]] auto const& param1) -> void;
auto no_return([[maybe_unused]] auto const& unnamed_param_1) -> void;

[[nodiscard]] auto ufcs(cpp2::in<int> i) -> int;
struct fun_ret { int i; };
Expand All @@ -31,7 +31,7 @@ auto no_return([[maybe_unused]] auto const& param1) -> void;

#line 39 "pure2-ufcs-member-access-and-chaining.cpp2"
// And a test for non-local UFCS, which shouldn't do a [&] capture
[[nodiscard]] auto f([[maybe_unused]] auto const& param1) -> int;
[[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_1) -> int;
extern int y;

//=== Cpp2 function definitions =================================================
Expand Down Expand Up @@ -59,7 +59,7 @@ extern int y;
CPP2_UFCS_0(no_return, 42);
}

auto no_return([[maybe_unused]] auto const& param1) -> void{}
auto no_return([[maybe_unused]] auto const& unnamed_param_1) -> void{}

[[nodiscard]] auto ufcs(cpp2::in<int> i) -> int{
return i + 2;
Expand All @@ -77,6 +77,6 @@ auto no_return([[maybe_unused]] auto const& param1) -> void{}
}

#line 40 "pure2-ufcs-member-access-and-chaining.cpp2"
[[nodiscard]] auto f([[maybe_unused]] auto const& param1) -> int { return 0; }
[[nodiscard]] auto f([[maybe_unused]] auto const& unnamed_param_1) -> int { return 0; }
int y {CPP2_UFCS_0_NONLOCAL(f, 0)};

2 changes: 1 addition & 1 deletion regression-tests/test-results/version
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

cppfront compiler v0.3.0 Build 8B07:1638
cppfront compiler v0.3.0 Build 8B09:1419
Copyright(c) Herb Sutter All rights reserved

SPDX-License-Identifier: CC-BY-NC-ND-4.0
Expand Down
2 changes: 1 addition & 1 deletion source/build.info
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"8B07:1638"
"8B09:1419"
28 changes: 28 additions & 0 deletions source/sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,34 @@ class sema
}


auto check(parameter_declaration_node const& n)
-> bool
{
auto type_name = std::string{};
if (n.declaration->has_declared_return_type()) {
type_name = n.declaration->get_object_type()->to_string();
}

if (
n.ordinal == 2
&& !n.has_name("that")
&& n.declaration->parent_declaration
&& n.declaration->parent_declaration->has_name("operator=")
&& n.declaration->parent_declaration->parent_declaration
&& n.declaration->parent_declaration->parent_declaration->name()
&& type_name == *n.declaration->parent_declaration->parent_declaration->name()
)
{
errors.emplace_back(
n.position(),
"if an 'operator=' second parameter is of the same type (here '" + type_name + "'), it must be named 'that'"
);
return false;
}

return true;
}

auto check(declaration_node const& n)
-> bool
{
Expand Down
Loading

0 comments on commit 76c2941

Please sign in to comment.