Skip to content

Commit

Permalink
Require an expression to initialize an object
Browse files Browse the repository at this point in the history
  • Loading branch information
ntrel committed Oct 20, 2023
1 parent 789cd38 commit 9bd9f9a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
19 changes: 19 additions & 0 deletions regression-tests/pure2-object-init-expression.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
v : std::any = 12;

main: () = {
// object initializer must be an expression, not a statement
// inspect requires a result type when it is an expression
i: int = inspect v -> int {
is 12 = 12;
is _ = 0;
};
[[assert: i == 12]]

// inference
s := inspect v -> std::string {
is 5 = "five";
is int = "some other integer";
is _ = "not an integer";
};
[[assert: s == "some other integer"]]
}
38 changes: 38 additions & 0 deletions regression-tests/test-results/pure2-object-init-expression.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@


//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"



//=== Cpp2 type definitions and function declarations ===========================

extern std::any v;

auto main() -> int;


//=== Cpp2 function definitions =================================================

std::any v {12};

auto main() -> int{
// object initializer must be an expression, not a statement
// inspect requires a result type when it is an expression
int i {[&] () -> int { auto&& _expr = v;
if (cpp2::is(_expr, 12)) { if constexpr( requires{12;} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF((12)),int> ) return 12; else return int{}; else return int{}; }
else return 0; }
()};
cpp2::Default.expects(std::move(i) == 12, "");

// inference
auto s {[&] () -> std::string { auto&& _expr = v;
if (cpp2::is(_expr, 5)) { if constexpr( requires{"five";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("five")),std::string> ) return "five"; else return std::string{}; else return std::string{}; }
else if (cpp2::is<int>(_expr)) { if constexpr( requires{"some other integer";} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF(("some other integer")),std::string> ) return "some other integer"; else return std::string{}; else return std::string{}; }
else return "not an integer"; }
()};
cpp2::Default.expects(std::move(s) == "some other integer", "");
}

13 changes: 12 additions & 1 deletion source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -8025,7 +8025,18 @@ class parser
}
}

if (!(n->initializer = statement(semicolon_required, n->equal_sign))) {
if (n->is_object()) {
// Require an expression to initialize an object
auto es = expression_statement(semicolon_required);
if (es) {
n->initializer = std::make_unique<statement_node>();
n->initializer->statement = std::move(es);
}
}
else {
n->initializer = statement(semicolon_required, n->equal_sign);
}
if (!n->initializer) {
error(
"ill-formed initializer",
true, {}, true
Expand Down

0 comments on commit 9bd9f9a

Please sign in to comment.