Skip to content

Commit

Permalink
feat: add _type-id_ production for decltype
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Oct 3, 2024
1 parent c5feb42 commit 643aebd
Show file tree
Hide file tree
Showing 15 changed files with 82 additions and 12 deletions.
2 changes: 1 addition & 1 deletion regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ d: _ == t<o.f()>(); // Fails on Clang 12 (lambda in unevaluated context).

u: @struct type = {
b: bool == o.f();
c: bool == :(x: std::type_identity_t<decltype(o.f())>) x;(true); // Fails on Clang 12 (lambda in unevaluated context).
c: bool == :(x: decltype(o.f())) x;(true); // Fails on Clang 12 (lambda in unevaluated context).
g: (s, sz) pre(s.sz() != 0) = { }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

v: <T> concept = :() -> bool = true;();

u: type == std::type_identity_t<decltype(:() = {})>;
u: type == decltype(:() = {});

t: @struct type = {
this: std::type_identity_t<decltype(:() = {})>;
this: decltype(:() = {});
}

main: () = { }
1 change: 1 addition & 0 deletions regression-tests/pure2-deduction-1-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f: () -> decltype(auto) = 0;
1 change: 1 addition & 0 deletions regression-tests/pure2-deduction-2-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x: decltype(auto) = 0;
2 changes: 1 addition & 1 deletion regression-tests/pure2-last-use.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ issue_313: () = {
_ = e is (e);

f := new<int>(0);
_ = f is std::type_identity_t<decltype(f)>; // OK?
_ = f is decltype(f); // OK?

g := new<int>(0);
for (identity(g)* + identity(g)*)
Expand Down
2 changes: 2 additions & 0 deletions regression-tests/pure2-print.cpp2
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ outer: @print type = {
all: <Args...: type> (args...: Args) -> bool =
(... && args);

y: (_: decltype(0)) = { }

}

main: () = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ auto g() -> void{

#line 40 "mixed-bugfix-for-ufcs-non-local.cpp2"
inline CPP2_CONSTEXPR bool u::b{ CPP2_UFCS_NONLOCAL(f)(o) };
inline CPP2_CONSTEXPR bool u::c{ [](cpp2::impl::in<std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(f)(o))>> x) -> auto { return x; }(true) };// Fails on Clang 12 (lambda in unevaluated context).
inline CPP2_CONSTEXPR bool u::c{ [](cpp2::impl::in<decltype(CPP2_UFCS_NONLOCAL(f)(o))> x) -> auto { return x; }(true) };// Fails on Clang 12 (lambda in unevaluated context).
auto u::g(auto const& s, auto const& sz) -> void{
if (cpp2::cpp2_default.is_active() && !(CPP2_UFCS(sz)(s) != 0) ) { cpp2::cpp2_default.report_violation(""); }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class t;
#line 5 "pure2-bugfix-for-non-local-function-expression.cpp2"
template<typename T> concept v = []() -> bool { return true; }();

using u = std::type_identity_t<decltype([]() -> void{})>;
using u = decltype([]() -> void{});

class t: public std::type_identity_t<decltype([]() -> void{})> {
class t: public decltype([]() -> void{}) {

};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pure2-deduction-1-error.cpp2...
pure2-deduction-1-error.cpp2(1,10): error: decltype(auto) is not needed in Cpp2 - use 'forward: _' parameters/returns/objects instead
(temporary alpha limitation) returns means auto&&
(temporary alpha limitation) objects are not yet supported

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pure2-deduction-2-error.cpp2...
pure2-deduction-2-error.cpp2(1,4): error: decltype(auto) is not needed in Cpp2 - use 'forward: _' parameters/returns/objects instead
(temporary alpha limitation) returns means auto&&
(temporary alpha limitation) objects are not yet supported

2 changes: 1 addition & 1 deletion regression-tests/test-results/pure2-last-use.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ auto issue_313() -> void{
static_cast<void>(cpp2::impl::is(e, (e)));

auto f {cpp2_new<int>(0)};
static_cast<void>(cpp2::impl::is<std::type_identity_t<decltype(f)>>(f));// OK?
static_cast<void>(cpp2::impl::is<decltype(f)>(f));// OK?

auto g {cpp2_new<int>(0)};
for (
Expand Down
10 changes: 8 additions & 2 deletions regression-tests/test-results/pure2-print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ CPP2_REQUIRES_ (cpp2::impl::cmp_greater_eq(sizeof...(Args),0u)) ;

#line 100 "pure2-print.cpp2"
public: template<typename ...Args> [[nodiscard]] static auto all(Args const& ...args) -> bool;

#line 103 "pure2-print.cpp2"
public: static auto y([[maybe_unused]] cpp2::impl::in<decltype(0)> unnamed_param_1) -> void;
public: outer() = default;
public: outer(outer const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(outer const&) -> void = delete;


#line 103 "pure2-print.cpp2"
#line 105 "pure2-print.cpp2"
};

auto main() -> int;
Expand Down Expand Up @@ -199,7 +202,10 @@ requires (cpp2::impl::cmp_greater_eq(sizeof...(Args),0u)) {
template<typename ...Args> [[nodiscard]] auto outer::all(Args const& ...args) -> bool {
return (... && args); }

#line 105 "pure2-print.cpp2"
#line 103 "pure2-print.cpp2"
auto outer::y([[maybe_unused]] cpp2::impl::in<decltype(0)> unnamed_param_1) -> void{}

#line 107 "pure2-print.cpp2"
auto main() -> int{
outer::test();
}
Expand Down
4 changes: 4 additions & 0 deletions regression-tests/test-results/pure2-print.cpp2.output
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ outer:/* @print */ type =
}

all: <Args...: type, >(in args...: Args, ) -> move bool = (... && args);

y:(in _: decltype(0), ) =
{
}
}
ok (all Cpp2, passes safety checks)

49 changes: 47 additions & 2 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -1365,9 +1365,10 @@ struct type_id_node
int dereference_cnt = {};
token const* suspicious_initialization = {};

enum active : u8 { empty=0, qualified, unqualified, function, keyword };
enum active : u8 { empty=0, decltype_, qualified, unqualified, function, keyword };
std::variant<
std::monostate,
std::unique_ptr<postfix_expression_node>,
std::unique_ptr<qualified_id_node>,
std::unique_ptr<unqualified_id_node>,
std::unique_ptr<function_type_node>,
Expand Down Expand Up @@ -1419,6 +1420,9 @@ struct type_id_node
if (id.index() == unqualified) {
return std::get<unqualified>(id)->template_arguments();
}
else if (id.index() != qualified) {
cpp2_default.report_violation("ICE: this type_id has no template arguments");
}
// else
return std::get<qualified>(id)->template_arguments();
}
Expand All @@ -1432,6 +1436,8 @@ struct type_id_node
switch (id.index()) {
break;case empty:
return {};
break;case decltype_:
return {};
break;case qualified:
return {};
break;case unqualified:
Expand Down Expand Up @@ -1460,6 +1466,7 @@ struct type_id_node
for (auto q : pc_qualifiers) {
v.start(*q, depth+1);
}
try_visit<decltype_ >(id, v, depth);
try_visit<qualified >(id, v, depth);
try_visit<unqualified>(id, v, depth);
try_visit<function >(id, v, depth);
Expand Down Expand Up @@ -2770,6 +2777,8 @@ auto type_id_node::to_string() const
switch (id.index()) {
break;case empty:
ret += "_";
break;case decltype_:
ret += std::get<decltype_>(id)->to_string();
break;case qualified:
ret += std::get<qualified>(id)->to_string();
break;case unqualified:
Expand Down Expand Up @@ -5084,6 +5093,7 @@ auto pretty_print_visualize(type_id_node const& n, int indent)
}

if (n.id.index() == type_id_node::empty) { ret += "_"; }
ret += try_pretty_print_visualize<type_id_node::decltype_ >(n.id, indent);
ret += try_pretty_print_visualize<type_id_node::qualified >(n.id, indent);
ret += try_pretty_print_visualize<type_id_node::unqualified>(n.id, indent);
ret += try_pretty_print_visualize<type_id_node::function >(n.id, indent);
Expand Down Expand Up @@ -6867,6 +6877,7 @@ class parser


//G type-id:
//G type-qualifier-seq? 'decltype' '(' expression ')' is-type-constraint?
//G type-qualifier-seq? qualified-id is-type-constraint?
//G type-qualifier-seq? unqualified-id is-type-constraint?
//G type-qualifier-seq? function-type is-type-constraint?
Expand Down Expand Up @@ -6909,7 +6920,41 @@ class parser
next();
}

if (auto id = qualified_id()) {
if (auto& c = curr();
c == "decltype"
)
{
if (
peek(1) && peek(1)->type() == lexeme::LeftParen
&& peek(2) && *peek(2) == "auto"
&& peek(3) && peek(3)->type() == lexeme::RightParen)
{
error(
"decltype(auto) is not needed in Cpp2 - use 'forward: _' parameters/returns/objects instead"
"\n (temporary alpha limitation) returns means auto&&"
"\n (temporary alpha limitation) objects are not yet supported",
false,
c.position()
);
}
if (auto id = postfix_expression();
id
&& id->ops.size() == 1
&& id->ops[0].expr_list->expressions.size() == 1
&& id->ops[0].expr_list->open_paren->type() == lexeme::LeftParen
)
{
n->pos = id->position();
n->id = std::move(id);
assert (n->id.index() == type_id_node::decltype_);
}
else
{
error("'decltype' must be followed by a single parenthesized expression", false, c.position());
return {};
}
}
else if (auto id = qualified_id()) {
n->pos = id->position();
n->id = std::move(id);
assert (n->id.index() == type_id_node::qualified);
Expand Down
1 change: 1 addition & 0 deletions source/to_cpp1.h
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,7 @@ class cppfront
else {
try_emit<type_id_node::unqualified>(n.id, 0, false);
try_emit<type_id_node::qualified >(n.id);
try_emit<type_id_node::decltype_ >(n.id);
try_emit<type_id_node::keyword >(n.id);
}

Expand Down

0 comments on commit 643aebd

Please sign in to comment.