Skip to content

Commit f3d6819

Browse files
hsutterzaucy
authored andcommitted
Add mandatory explicit discard, closes hsutter#305
Support `_ =` as a discard operation - for example, `_ = vec.emplace_back(a,b,c);` - emitted as `(void)`, not `std::ignore =` because the latter doesn't work with `void` returns and we want to support generic code where there might or might not be a return value in a given template instantiation Make UFCS calls unconditionally add [[nodiscard]] always - note: only added on compilers that support C++23's P2173 Take back `_ :=` as an anonymous deduced variable syntax - the name can be anonymous or the type can be anonymous, but not both - yes, it would be easy to support making both anonymous (it did work before this commit, which had to explicitly add a check to disable it) - rationale: if that were allowed to keep the returned object alive, that syntax would be dangerously close to '_ = f();' to discard the returned object, which is exactly opposite in a fundamentally important way (lifetime!) and such importantly opposite meanings deserve more than a one-character typo distance - explicit discarding gets the nice syntax because it's likely more common - but this shouldn't be any hardship because cases that use a type are still just as easy, e.g., `lock_guard`; before this commit `_ := lock_guard(mut);` worked, and after this commit that's disallowed but it's just as easy to write `_: lock_guard = mut;` - to make this natural also for `finally`, I just got rid of the `finally` and `finally_success` helper functions, and gave those names to the types... it's a simpler design and I think an improvement in its own right, and `_: finally = code;` is slightly simpler to write (e.g., saves `(` `)` `;`, for example see `pure2-types-order-independence-and-nesting.cpp2`) Remove return type from `contract_group::set_handler` - not needed, since we already have `get_handler` if the current value is of interest Add reflection `default_to_*` functions for `make_*` functions that ignore the returned bool - arguably a clearer API, makes calling code intent more readable
1 parent 99ed801 commit f3d6819

25 files changed

+234
-166
lines changed

include/cpp2util.h

+44-39
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,8 @@ class contract_group {
325325
using handler = void (*)(CPP2_MESSAGE_PARAM msg CPP2_SOURCE_LOCATION_PARAM);
326326

327327
constexpr contract_group (handler h = {}) : reporter(h) { }
328-
constexpr auto set_handler(handler h) -> handler;
329-
constexpr auto get_handler() const -> handler { return reporter; }
328+
constexpr auto set_handler(handler h);
329+
constexpr auto get_handler() const -> handler { return reporter; }
330330
constexpr auto expects (bool b, CPP2_MESSAGE_PARAM msg = "" CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT)
331331
-> void { if (!b) reporter(msg CPP2_SOURCE_LOCATION_ARG); }
332332
private:
@@ -374,11 +374,9 @@ auto inline Testing = contract_group(
374374
}
375375
);
376376

377-
constexpr auto contract_group::set_handler(handler h) -> handler {
377+
constexpr auto contract_group::set_handler(handler h) {
378378
Default.expects(h);
379-
auto old = reporter;
380379
reporter = h;
381-
return old;
382380
}
383381

384382

@@ -685,16 +683,33 @@ class out {
685683
#ifdef _MSC_VER
686684
#define CPP2_FORCE_INLINE __forceinline
687685
#define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]]
686+
#define CPP2_LAMBDA_NO_DISCARD
688687
#else
689688
#define CPP2_FORCE_INLINE __attribute__((always_inline))
690689
#define CPP2_FORCE_INLINE_LAMBDA __attribute__((always_inline))
690+
691+
#if defined(__clang_major__)
692+
#if (__clang_major__ > 13 || (__clang_major__ == 13 && __clang_minor__ >= 2))
693+
#define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
694+
#else
695+
#define CPP2_LAMBDA_NO_DISCARD
696+
#endif
697+
#elif defined(__GNUC__)
698+
#if __GNUC__ >= 9
699+
#define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
700+
#else
701+
#define CPP2_LAMBDA_NO_DISCARD
702+
#endif
703+
#else
704+
#define CPP2_LAMBDA_NO_DISCARD
705+
#endif
691706
#endif
692707

693708

694709
// Note: [&] is because a nested UFCS might be viewed as trying to capture 'this'
695710

696711
#define CPP2_UFCS(FUNCNAME,PARAM1,...) \
697-
[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
712+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
698713
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \
699714
return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
700715
} else { \
@@ -703,7 +718,7 @@ class out {
703718
}(PARAM1, __VA_ARGS__)
704719

705720
#define CPP2_UFCS_0(FUNCNAME,PARAM1) \
706-
[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
721+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
707722
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
708723
return CPP2_FORWARD(obj).FUNCNAME(); \
709724
} else { \
@@ -714,7 +729,7 @@ class out {
714729
#define CPP2_UFCS_REMPARENS(...) __VA_ARGS__
715730

716731
#define CPP2_UFCS_TEMPLATE(FUNCNAME,TEMPARGS,PARAM1,...) \
717-
[&](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
732+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
718733
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \
719734
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \
720735
} else { \
@@ -723,7 +738,7 @@ class out {
723738
}(PARAM1, __VA_ARGS__)
724739

725740
#define CPP2_UFCS_TEMPLATE_0(FUNCNAME,TEMPARGS,PARAM1) \
726-
[&](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
741+
[&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
727742
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
728743
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
729744
} else { \
@@ -735,7 +750,7 @@ class out {
735750
// But for non-local lambdas [&] is not allowed
736751

737752
#define CPP2_UFCS_NONLOCAL(FUNCNAME,PARAM1,...) \
738-
[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
753+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
739754
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); }) { \
740755
return CPP2_FORWARD(obj).FUNCNAME(CPP2_FORWARD(params)...); \
741756
} else { \
@@ -744,7 +759,7 @@ class out {
744759
}(PARAM1, __VA_ARGS__)
745760

746761
#define CPP2_UFCS_0_NONLOCAL(FUNCNAME,PARAM1) \
747-
[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
762+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
748763
if constexpr (requires{ CPP2_FORWARD(obj).FUNCNAME(); }) { \
749764
return CPP2_FORWARD(obj).FUNCNAME(); \
750765
} else { \
@@ -753,7 +768,7 @@ class out {
753768
}(PARAM1)
754769

755770
#define CPP2_UFCS_TEMPLATE_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1,...) \
756-
[](auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
771+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj, auto&& ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
757772
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); }) { \
758773
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD(params)...); \
759774
} else { \
@@ -762,7 +777,7 @@ class out {
762777
}(PARAM1, __VA_ARGS__)
763778

764779
#define CPP2_UFCS_TEMPLATE_0_NONLOCAL(FUNCNAME,TEMPARGS,PARAM1) \
765-
[](auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
780+
[] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
766781
if constexpr (requires{ CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
767782
return CPP2_FORWARD(obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
768783
} else { \
@@ -1347,70 +1362,60 @@ constexpr auto as( X const& x ) -> decltype(auto)
13471362
//
13481363

13491364
template <class F>
1350-
class final_action_success
1365+
class finally_success
13511366
{
13521367
public:
1353-
explicit final_action_success(const F& ff) noexcept : f{ff} { }
1354-
explicit final_action_success(F&& ff) noexcept : f{std::move(ff)} { }
1368+
explicit finally_success(const F& ff) noexcept : f{ff} { }
1369+
explicit finally_success(F&& ff) noexcept : f{std::move(ff)} { }
13551370

1356-
~final_action_success() noexcept
1371+
~finally_success() noexcept
13571372
{
13581373
if (invoke && ecount == std::uncaught_exceptions()) {
13591374
f();
13601375
}
13611376
}
13621377

1363-
final_action_success(final_action_success&& that) noexcept
1378+
finally_success(finally_success&& that) noexcept
13641379
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false))
13651380
{ }
13661381

1367-
final_action_success(final_action_success const&) = delete;
1368-
void operator= (final_action_success const&) = delete;
1369-
void operator= (final_action_success&&) = delete;
1382+
finally_success(finally_success const&) = delete;
1383+
void operator= (finally_success const&) = delete;
1384+
void operator= (finally_success&&) = delete;
13701385

13711386
private:
13721387
F f;
13731388
int ecount = std::uncaught_exceptions();
13741389
bool invoke = true;
13751390
};
13761391

1377-
[[nodiscard]] auto finally_success(auto&& f) noexcept
1378-
{
1379-
return final_action_success<CPP2_TYPEOF(f)>{CPP2_FORWARD(f)};
1380-
}
1381-
13821392

13831393
//
13841394
// Same, but clean up also on exceptional paths
13851395
//
13861396

13871397
template <class F>
1388-
class final_action
1398+
class finally
13891399
{
13901400
public:
1391-
explicit final_action(const F& ff) noexcept : f{ff} { }
1392-
explicit final_action(F&& ff) noexcept : f{std::move(ff)} { }
1401+
explicit finally(const F& ff) noexcept : f{ff} { }
1402+
explicit finally(F&& ff) noexcept : f{std::move(ff)} { }
13931403

1394-
~final_action() noexcept { f(); }
1404+
~finally() noexcept { f(); }
13951405

1396-
final_action(final_action&& that) noexcept
1406+
finally(finally&& that) noexcept
13971407
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false))
13981408
{ }
13991409

1400-
final_action (final_action const&) = delete;
1401-
void operator=(final_action const&) = delete;
1402-
void operator=(final_action&&) = delete;
1410+
finally (finally const&) = delete;
1411+
void operator=(finally const&) = delete;
1412+
void operator=(finally&&) = delete;
14031413

14041414
private:
14051415
F f;
14061416
bool invoke = true;
14071417
};
14081418

1409-
[[nodiscard]] auto finally(auto&& f) noexcept
1410-
{
1411-
return final_action<CPP2_TYPEOF(f)>{CPP2_FORWARD(f)};
1412-
}
1413-
14141419

14151420
//-----------------------------------------------------------------------
14161421
//

regression-tests/mixed-captures-in-expressions-and-postconditions.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ insert_at: (where: int, val: int)
2020
[[pre: 0 <= where && where <= vec.ssize()]]
2121
[[post: vec.ssize() == vec.ssize()$ + 1]]
2222
= {
23-
vec.insert( vec.begin()+where, val );
23+
_ = vec.insert( vec.begin()+where, val );
2424
}

regression-tests/pure2-inspect-expression-in-generic-function-multiple-types.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ main: () -> int = {
88
test_generic(a, "any");
99
test_generic(o, "optional<int>");
1010

11-
v.emplace<0>(1);
11+
_ = v.emplace<0>(1);
1212
a = 2;
1313
o = 3;
1414
test_generic(42, "int");

regression-tests/pure2-stdio-with-raii.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
main: () -> int = {
55
s: std::string = "Freddy";
66
myfile := cpp2::fopen("xyzzy", "w");
7-
myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
7+
_ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
88
}

regression-tests/pure2-stdio.cpp2

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
main: () -> int = {
55
s: std::string = "Fred";
66
myfile := fopen("xyzzy", "w");
7-
myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
8-
myfile.fclose();
7+
_ = myfile.fprintf( "Hello %s with UFCS!", s.c_str() );
8+
_ = myfile.fclose();
99
}
1010

regression-tests/pure2-type-safety-1.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ main: () -> int =
1212

1313
std::cout << "\n";
1414

15-
v.emplace<1>(1);
15+
_ = v.emplace<1>(1);
1616
a = 2;
1717
o = 3;
1818
test_generic(42, "int");

regression-tests/pure2-type-safety-2-with-inspect-expression.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ main: () -> int = {
88
test_generic(a, "any");
99
test_generic(o, "optional<int>");
1010

11-
v.emplace<2>(1);
11+
_ = v.emplace<2>(1);
1212
a = 2;
1313
o = 3;
1414
test_generic(42, "int");

regression-tests/pure2-types-order-independence-and-nesting.cpp2

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ X: type = {
3434
// X::exx member function description here
3535
exx: (this, count: int) = {
3636
// Exercise '_' anonymous objects too while we're at it
37-
_ := finally( :()= std::cout << "leaving call to 'why((count)$)'\n"; );
37+
_: finally = :()= std::cout << "leaving call to 'why((count)$)'\n";
3838
if count < 5 {
3939
py*.why( count+1 ); // use Y object from X
4040
}

regression-tests/pure2-ufcs-member-access-and-chaining.cpp2

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
main: () -> int = {
22
i := 42;
3-
i.ufcs();
3+
_ = i.ufcs();
44

55
j := fun();
6-
j.i.ufcs();
6+
_ = j.i.ufcs();
77

8-
fun().i.ufcs();
8+
_ = fun().i.ufcs();
99

1010
k := fun().i;
11-
k.ufcs();
11+
_ = k.ufcs();
1212

13-
get_i(j).ufcs();
13+
_ = get_i(j).ufcs();
1414

15-
get_i(fun()).ufcs();
15+
_ = get_i(fun()).ufcs();
1616

1717
res := (42).ufcs();
1818

19-
(j.i).ufcs();
19+
_ = (j.i).ufcs();
20+
21+
_ = 42.no_return();
2022
}
2123

24+
no_return: (x: int) = { }
25+
2226
ufcs: (i:int) -> int = {
2327
return i+2;
2428
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ auto insert_at(cpp2::in<int> where, cpp2::in<int> val) -> void
4848
cpp2::Default.expects(cpp2::cmp_less_eq(0,where) && cpp2::cmp_less_eq(where,CPP2_UFCS_0(ssize, vec)), "");
4949
auto post_21_5 = cpp2::finally_success([_0 = CPP2_UFCS_0(ssize, vec)]{cpp2::Default.expects(CPP2_UFCS_0(ssize, vec)==_0 + 1, "");} );
5050
#line 23 "mixed-captures-in-expressions-and-postconditions.cpp2"
51-
CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val);
51+
(void) CPP2_UFCS(insert, vec, CPP2_UFCS_0(begin, vec) + where, val);
5252
}
5353

regression-tests/test-results/pure2-cpp1-multitoken-fundamental-types-error.cpp2.output

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
pure2-cpp1-multitoken-fundamental-types-error.cpp2...
2-
pure2-cpp1-multitoken-fundamental-types-error.cpp2(3,8): error: 'signed short int' - did you mean cpp2::'short'?
2+
pure2-cpp1-multitoken-fundamental-types-error.cpp2(3,8): error: 'signed short int' - did you mean 'short'?
33
pure2-cpp1-multitoken-fundamental-types-error.cpp2(3,8): error: 'signed short int' is an old-style C/C++ multi-word keyword type
44
- most such types should be used only for interoperability with older code
55
- using those when you need them is fine, but name them with these short names instead:
66
short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, __schar, __uchar
77
- see also cpp2util.h > "Convenience names for integer types"
8-
pure2-cpp1-multitoken-fundamental-types-error.cpp2(4,8): error: 'short int signed' - did you mean cpp2::'short'?
8+
pure2-cpp1-multitoken-fundamental-types-error.cpp2(4,8): error: 'short int signed' - did you mean 'short'?
99
pure2-cpp1-multitoken-fundamental-types-error.cpp2(4,8): error: 'short int signed' is an old-style C/C++ multi-word keyword type
1010
- most such types should be used only for interoperability with older code
1111
- using those when you need them is fine, but name them with these short names instead:
1212
short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, __schar, __uchar
1313
- see also cpp2util.h > "Convenience names for integer types"
14-
pure2-cpp1-multitoken-fundamental-types-error.cpp2(5,8): error: 'long long unsigned int' - did you mean cpp2::'ulonglong'?
14+
pure2-cpp1-multitoken-fundamental-types-error.cpp2(5,8): error: 'long long unsigned int' - did you mean 'ulonglong'?
1515
pure2-cpp1-multitoken-fundamental-types-error.cpp2(5,8): error: 'long long unsigned int' is an old-style C/C++ multi-word keyword type
1616
- most such types should be used only for interoperability with older code
1717
- using those when you need them is fine, but name them with these short names instead:
1818
short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, __schar, __uchar
1919
- see also cpp2util.h > "Convenience names for integer types"
20-
pure2-cpp1-multitoken-fundamental-types-error.cpp2(6,8): error: 'long double' - did you mean cpp2::'long'?
20+
pure2-cpp1-multitoken-fundamental-types-error.cpp2(6,8): error: 'long double' - did you mean 'long'?
2121
pure2-cpp1-multitoken-fundamental-types-error.cpp2(6,8): error: 'long double' is an old-style C/C++ multi-word keyword type
2222
- most such types should be used only for interoperability with older code
2323
- using those when you need them is fine, but name them with these short names instead:
2424
short, ushort, int, uint, long, ulong, longlong, ulonglong, longdouble, __schar, __uchar
2525
- see also cpp2util.h > "Convenience names for integer types"
26-
pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' - did you mean cpp2::'u8' (usually best) or '__uchar'?
26+
pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' - did you mean 'u8' (usually best) or 'cpp2::__uchar'?
2727
pure2-cpp1-multitoken-fundamental-types-error.cpp2(7,8): error: 'unsigned char' is an old-style C/C++ multi-word keyword type
2828
- most such types should be used only for interoperability with older code
2929
- using those when you need them is fine, but name them with these short names instead:

regression-tests/test-results/pure2-inspect-expression-in-generic-function-multiple-types.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void;
3131
test_generic(a, "any");
3232
test_generic(o, "optional<int>");
3333

34-
CPP2_UFCS_TEMPLATE(emplace, (<0>), v, 1);
34+
(void) CPP2_UFCS_TEMPLATE(emplace, (<0>), v, 1);
3535
a = 2;
3636
o = 3;
3737
test_generic(42, "int");

regression-tests/test-results/pure2-stdio-with-raii.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@
2424
[[nodiscard]] auto main() -> int{
2525
std::string s {"Freddy"};
2626
auto myfile {cpp2::fopen("xyzzy", "w")};
27-
CPP2_UFCS(fprintf, std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)));
27+
(void) CPP2_UFCS(fprintf, std::move(myfile), "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)));
2828
}
2929

regression-tests/test-results/pure2-stdio.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
[[nodiscard]] auto main() -> int{
2828
std::string s {"Fred"};
2929
auto myfile {fopen("xyzzy", "w")};
30-
CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)));
31-
CPP2_UFCS_0(fclose, std::move(myfile));
30+
(void) CPP2_UFCS(fprintf, myfile, "Hello %s with UFCS!", CPP2_UFCS_0(c_str, std::move(s)));
31+
(void) CPP2_UFCS_0(fclose, std::move(myfile));
3232
}
3333

regression-tests/test-results/pure2-type-safety-1.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ auto print(cpp2::in<std::string> msg, cpp2::in<bool> b) -> void;
4242

4343
std::cout << "\n";
4444

45-
CPP2_UFCS_TEMPLATE(emplace, (<1>), v, 1);
45+
(void) CPP2_UFCS_TEMPLATE(emplace, (<1>), v, 1);
4646
a = 2;
4747
o = 3;
4848
test_generic(42, "int");

regression-tests/test-results/pure2-type-safety-2-with-inspect-expression.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ auto test_generic(auto const& x, auto const& msg) -> void;
3131
test_generic(a, "any");
3232
test_generic(o, "optional<int>");
3333

34-
CPP2_UFCS_TEMPLATE(emplace, (<2>), v, 1);
34+
(void) CPP2_UFCS_TEMPLATE(emplace, (<2>), v, 1);
3535
a = 2;
3636
o = 3;
3737
test_generic(42, "int");

0 commit comments

Comments
 (0)