Skip to content

Commit d74b2ff

Browse files
committed
Enable natural use of single named return value
Given: f: () -> (ret: int = 42) = { // ... } The call site `f().ret` has always worked, as it should for a named return. The call site `f()` now also works -- we can omit the name if we don't need it. This lets callers have the same convenience of a single unnamed return value, while giving function authors the convenience of writing a named return value, including so the return value has a name for postconditions: f: () -> (ret: int = 42) post (ret > 0) = { // ... }
1 parent c1d3e0e commit d74b2ff

9 files changed

+43
-26
lines changed

regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ auto insert_at(cpp2::in<int> where, cpp2::in<int> val) -> void
4747
#line 22 "mixed-captures-in-expressions-and-postconditions.cpp2"
4848
{
4949
cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), "");
50-
auto post_21_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec) == _0 + 1, "");} );
50+
auto post_21_5 = cpp2::finally_success([&, _1 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec) == _1 + 1, "");} );
5151
#line 23 "mixed-captures-in-expressions-and-postconditions.cpp2"
5252
static_cast<void>(CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val));
5353
}

regression-tests/test-results/mixed-postexpression-with-capture.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ auto insert_at(cpp2::in<int> where, cpp2::in<int> val) -> void
4242
#line 17 "mixed-postexpression-with-capture.cpp2"
4343
{
4444
cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), "");
45-
auto post_16_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(size, vec)]{cpp2::Default.expects(CPP2_UFCS_0(size, vec) == _0 + 1, "");} );
45+
auto post_16_5 = cpp2::finally_success([&, _1 = CPP2_UFCS_0(size, vec)]{cpp2::Default.expects(CPP2_UFCS_0(size, vec) == _1 + 1, "");} );
4646
#line 18 "mixed-postexpression-with-capture.cpp2"
4747
CPP2_UFCS(push_back, vec, val);
4848
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Microsoft (R) C/C++ Optimizing Compiler Version 19.37.32825 for x86
1+
Microsoft (R) C/C++ Optimizing Compiler Version 19.37.32826.1 for x86
22
Copyright (C) Microsoft Corporation. All rights reserved.
33

regression-tests/test-results/pure2-bugfix-for-name-lookup-and-value-decoration.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
#line 1 "pure2-bugfix-for-name-lookup-and-value-decoration.cpp2"
1515

16-
struct vals_ret { int i; };
16+
struct vals_ret { int i;
17+
operator auto() const { return i; }};
1718

1819
[[nodiscard]] auto vals() -> vals_ret;
1920

regression-tests/test-results/pure2-look-up-parameter-across-unnamed-function.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313

1414
#line 1 "pure2-look-up-parameter-across-unnamed-function.cpp2"
1515

16-
struct f_ret { int ri; };
16+
struct f_ret { int ri;
17+
operator auto() const { return ri; }};
1718

1819
#line 2 "pure2-look-up-parameter-across-unnamed-function.cpp2"
1920
[[nodiscard]] auto f() -> f_ret;
20-
struct g_ret { int ri; };
21+
struct g_ret { int ri;
22+
operator auto() const { return ri; }};
2123

2224

2325

regression-tests/test-results/pure2-ufcs-member-access-and-chaining.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
auto no_return([[maybe_unused]] auto const& unnamed_param_1) -> void;
1919

2020
[[nodiscard]] auto ufcs(cpp2::in<int> i) -> int;
21-
struct fun_ret { int i; };
21+
struct fun_ret { int i;
22+
operator auto() const { return i; }};
2223

2324

2425

regression-tests/test-results/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.3.0 Build 8B15:0741
2+
cppfront compiler v0.3.0 Build 8B15:1925
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8B15:0741"
1+
"8B15:1925"

source/to_cpp1.h

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,7 +2460,8 @@ class cppfront
24602460
//
24612461
auto build_capture_lambda_intro_for(
24622462
capture_group& captures,
2463-
source_position pos
2463+
source_position pos,
2464+
bool include_default_reference_capture = false
24642465
)
24652466
-> std::string
24662467
{
@@ -2499,9 +2500,11 @@ class cppfront
24992500
auto num_captures = 0;
25002501

25012502
if (
2502-
!current_functions.empty()
2503-
&& current_functions.back().decl->is_function_with_this()
2504-
&& !current_functions.back().decl->parent_is_namespace()
2503+
(!current_functions.empty()
2504+
&& current_functions.back().decl->is_function_with_this()
2505+
&& !current_functions.back().decl->parent_is_namespace()
2506+
)
2507+
|| include_default_reference_capture
25052508
)
25062509
{
25072510
// Note: & is needed (when allowed, not at namespace scope) because a
@@ -4239,7 +4242,8 @@ class cppfront
42394242
auto emit(
42404243
parameter_declaration_list_node const& n,
42414244
bool is_returns = false,
4242-
bool is_template_parameter = false
4245+
bool is_template_parameter = false,
4246+
std::string extra_text = ""
42434247
)
42444248
-> void
42454249
{
@@ -4277,7 +4281,7 @@ class cppfront
42774281
}
42784282

42794283
if (is_returns) {
4280-
printer.print_extra( "};\n" );
4284+
printer.print_extra( extra_text + "};\n" );
42814285
}
42824286
else {
42834287
// Position heuristic (aka hack): Avoid emitting extra whitespace before )
@@ -4307,7 +4311,7 @@ class cppfront
43074311
// For a postcondition, we'll wrap it in a final_action_success lambda
43084312
//
43094313
if (*n.kind == "post") {
4310-
auto lambda_intro = build_capture_lambda_intro_for(n.captures, n.position());
4314+
auto lambda_intro = build_capture_lambda_intro_for(n.captures, n.position(), true);
43114315
printer.print_cpp2(
43124316
"auto post_" + std::to_string(n.position().lineno) + "_" +
43134317
std::to_string(n.position().colno) + " = cpp2::finally_success(" +
@@ -5318,7 +5322,16 @@ class cppfront
53185322
printer.print_extra( "\nstruct " );
53195323
printer.print_extra( *n.name() );
53205324
printer.print_extra( "_ret " );
5321-
emit(*r, true);
5325+
5326+
auto extra = std::string{};
5327+
if (std::ssize(r->parameters) == 1) {
5328+
assert (r->parameters[0]->declaration->name());
5329+
extra += "\noperator auto() const { return "
5330+
+ r->parameters[0]->declaration->name()->to_string()
5331+
+ "; }";
5332+
}
5333+
5334+
emit(*r, true, false, extra);
53225335
printer.print_extra( "\n" );
53235336
}
53245337
}
@@ -6030,15 +6043,6 @@ class cppfront
60306043
function_returns.emplace_back(nullptr); // no return type at all
60316044
}
60326045

6033-
for (auto&& c : func->contracts)
6034-
{
6035-
auto print = std::string();
6036-
printer.emit_to_string(&print);
6037-
emit(*c);
6038-
printer.emit_to_string();
6039-
current_functions.back().prolog.statements.push_back(print);
6040-
}
6041-
60426046
if (func->returns.index() == function_type_node::list)
60436047
{
60446048
auto& r = std::get<function_type_node::list>(func->returns);
@@ -6093,6 +6097,15 @@ class cppfront
60936097
}
60946098
}
60956099

6100+
for (auto&& c : func->contracts)
6101+
{
6102+
auto print = std::string();
6103+
printer.emit_to_string(&print);
6104+
emit(*c);
6105+
printer.emit_to_string();
6106+
current_functions.back().prolog.statements.push_back(print);
6107+
}
6108+
60966109
printer.preempt_position_push( n.equal_sign );
60976110

60986111
emit_requires_clause();

0 commit comments

Comments
 (0)