Skip to content

Commit ef8aa11

Browse files
committed
[libc++][expected] Applied [[nodiscard]]
[[nodiscard]] should be applied to functions where discarding the return value is most likely a correctness issue. - https://libcxx.llvm.org/CodingGuidelines.html - https://wg21.link/expected.bad.void - https://wg21.link/expected.bad - https://wg21.link/expected.expected - https://wg21.link/expected.void - https://wg21.link/expected.unexpected
1 parent 38678a9 commit ef8aa11

14 files changed

+346
-136
lines changed

libcxx/include/__expected/bad_expected_access.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_expected_access<void> : public exception {
4343

4444
public:
4545
# if _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION
46-
const char* what() const noexcept override;
46+
[[nodiscard]] const char* what() const noexcept override;
4747
# else
48-
_LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; }
48+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override {
49+
return "bad access to std::expected";
50+
}
4951
# endif
5052
};
5153
_LIBCPP_DIAGNOSTIC_POP
@@ -55,10 +57,10 @@ class bad_expected_access : public bad_expected_access<void> {
5557
public:
5658
_LIBCPP_HIDE_FROM_ABI explicit bad_expected_access(_Err __e) : __unex_(std::move(__e)) {}
5759

58-
_LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; }
59-
_LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; }
60-
_LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); }
61-
_LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); }
60+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Err& error() & noexcept { return __unex_; }
61+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const _Err& error() const& noexcept { return __unex_; }
62+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Err&& error() && noexcept { return std::move(__unex_); }
63+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI const _Err&& error() const&& noexcept { return std::move(__unex_); }
6264

6365
private:
6466
_Err __unex_;

libcxx/include/__expected/expected.h

Lines changed: 62 additions & 62 deletions
Large diffs are not rendered by default.

libcxx/include/__expected/unexpected.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ class unexpected {
8989
_LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(const unexpected&) = default;
9090
_LIBCPP_HIDE_FROM_ABI constexpr unexpected& operator=(unexpected&&) = default;
9191

92-
_LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
93-
_LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
94-
_LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
95-
_LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
92+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { return __unex_; }
93+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { return __unex_; }
94+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { return std::move(__unex_); }
95+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { return std::move(__unex_); }
9696

9797
_LIBCPP_HIDE_FROM_ABI constexpr void swap(unexpected& __other) noexcept(is_nothrow_swappable_v<_Err>) {
9898
static_assert(is_swappable_v<_Err>, "unexpected::swap requires is_swappable_v<E> to be true");

libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void test() {
5151
// U is not a specialization of std::expected
5252
{
5353
std::expected<int, int> f1(1);
54-
f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &)>' requested here}}
54+
(void)f1.and_then(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &)>' requested here}}
5555
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
5656
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
5757
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -61,7 +61,7 @@ void test() {
6161
// !std::is_same_v<U:error_type, E>
6262
{
6363
std::expected<int, int> f1(1);
64-
f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &)>' requested here}}
64+
(void)f1.and_then(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &)>' requested here}}
6565
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
6666
}
6767
}
@@ -71,7 +71,7 @@ void test() {
7171
// U is not a specialization of std::expected
7272
{
7373
const std::expected<int, int> f1(1);
74-
f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &)>' requested here}}
74+
(void)f1.and_then(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &)>' requested here}}
7575
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
7676
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
7777
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -81,7 +81,7 @@ void test() {
8181
// !std::is_same_v<U:error_type, E>
8282
{
8383
const std::expected<int, int> f1(1);
84-
f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &)>' requested here}}
84+
(void)f1.and_then(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &)>' requested here}}
8585
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
8686

8787
}
@@ -92,7 +92,7 @@ void test() {
9292
// U is not a specialization of std::expected
9393
{
9494
std::expected<int, int> f1(1);
95-
std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &&)>' requested here}}
95+
(void)std::move(f1).and_then(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(int &&)>' requested here}}
9696
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
9797
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
9898
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -102,7 +102,7 @@ void test() {
102102
// !std::is_same_v<U:error_type, E>
103103
{
104104
std::expected<int, int> f1(1);
105-
std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &&)>' requested here}}
105+
(void)std::move(f1).and_then(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(int &&)>' requested here}}
106106
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
107107
}
108108
}
@@ -112,7 +112,7 @@ void test() {
112112
// U is not a specialization of std::expected
113113
{
114114
const std::expected<int, int> f1(1);
115-
std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &&)>' requested here}}
115+
(void)std::move(f1).and_then(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<int (&)(const int &&)>' requested here}}
116116
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
117117
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
118118
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -122,7 +122,7 @@ void test() {
122122
// !std::is_same_v<U:error_type, E>
123123
{
124124
const std::expected<int, int> f1(1);
125-
std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &&)>' requested here}}
125+
(void)std::move(f1).and_then(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::and_then<std::expected<int, NotSameAsInt> (&)(const int &&)>' requested here}}
126126
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
127127
}
128128
}

libcxx/test/libcxx/utilities/expected/expected.expected/error_or.mandates.verify.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void test() {
3636
// !is_copy_constructible_v<G>,
3737
{
3838
const std::expected<int, NonCopyable> f1(std::unexpect, 0);
39-
f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonCopyable>::error_or<int>' requested here}}
39+
(void)f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonCopyable>::error_or<int>' requested here}}
4040
// expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be copy constructible}}
4141
// expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
4242
}
@@ -45,7 +45,7 @@ void test() {
4545
// !is_convertible_v<U, T>
4646
{
4747
const std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
48-
f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
48+
(void)f1.error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
4949
// expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
5050
// expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
5151

@@ -55,7 +55,7 @@ void test() {
5555
// !is_move_constructible_v<T>,
5656
{
5757
std::expected<int, NonMovable> f1(std::unexpect, 0);
58-
std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonMovable>::error_or<int>' requested here}}
58+
(void)std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NonMovable>::error_or<int>' requested here}}
5959
// expected-error-re@*:* {{static assertion failed {{.*}}error_type has to be move constructible}}
6060
// expected-error-re@*:* {{call to deleted constructor of{{.*}}}}
6161
}
@@ -64,7 +64,7 @@ void test() {
6464
// !is_convertible_v<U, T>
6565
{
6666
std::expected<int, NotConvertibleFromInt> f1(std::unexpect, NotConvertibleFromInt{});
67-
std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
67+
(void)std::move(f1).error_or(5); // expected-note{{in instantiation of function template specialization 'std::expected<int, NotConvertibleFromInt>::error_or<int>' requested here}}
6868
//expected-error-re@*:* {{static assertion failed {{.*}}argument has to be convertible to error_type}}
6969
// expected-error-re@*:* {{no viable conversion from returned value of type{{.*}}}}
7070
}

libcxx/test/libcxx/utilities/expected/expected.expected/or_else.mandates.verify.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void test() {
5151
// G is not a specialization of std::expected
5252
{
5353
std::expected<int, int> f1(std::unexpected<int>(1));
54-
f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &)>' requested here}}
54+
(void)f1.or_else(lval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &)>' requested here}}
5555
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
5656
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
5757
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -61,7 +61,7 @@ void test() {
6161
// !std::is_same_v<G:value_type, T>
6262
{
6363
std::expected<int, int> f1(std::unexpected<int>(1));
64-
f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}}
64+
(void)f1.or_else(lval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &)>' requested here}}
6565
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
6666
}
6767
}
@@ -71,7 +71,7 @@ void test() {
7171
// G is not a specialization of std::expected
7272
{
7373
const std::expected<int, int> f1(std::unexpected<int>(1));
74-
f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &)>' requested here}}
74+
(void)f1.or_else(clval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &)>' requested here}}
7575
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must be a specialization of std::expected}}
7676
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
7777
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -81,7 +81,7 @@ void test() {
8181
// !std::is_same_v<G:value_type, T>
8282
{
8383
const std::expected<int, int> f1(std::unexpected<int>(1));
84-
f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}}
84+
(void)f1.or_else(clval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &)>' requested here}}
8585
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(error()) must have the same value_type as this expected}}
8686
}
8787
}
@@ -91,7 +91,7 @@ void test() {
9191
// G is not a specialization of std::expected
9292
{
9393
std::expected<int, int> f1(std::unexpected<int>(1));
94-
std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &&)>' requested here}}
94+
(void)std::move(f1).or_else(rval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(int &&)>' requested here}}
9595
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
9696
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
9797
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -101,7 +101,7 @@ void test() {
101101
// !std::is_same_v<G:value_type, T>
102102
{
103103
std::expected<int, int> f1(std::unexpected<int>(1));
104-
std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}}
104+
(void)std::move(f1).or_else(rval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(int &&)>' requested here}}
105105
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
106106
}
107107
}
@@ -111,7 +111,7 @@ void test() {
111111
// G is not a specialization of std::expected
112112
{
113113
const std::expected<int, int> f1(std::unexpected<int>(1));
114-
std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &&)>' requested here}}
114+
(void)std::move(f1).or_else(crval_return_not_std_expected); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<int (&)(const int &&)>' requested here}}
115115
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must be a specialization of std::expected}}
116116
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
117117
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
@@ -121,7 +121,7 @@ void test() {
121121
// !std::is_same_v<G:value_type, T>
122122
{
123123
const std::expected<int, int> f1(std::unexpected<int>(1));
124-
std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}}
124+
(void)std::move(f1).or_else(crval_error_type_not_same_as_int); // expected-note{{in instantiation of function template specialization 'std::expected<int, int>::or_else<std::expected<NotSameAsInt, int> (&)(const int &&)>' requested here}}
125125
// expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(error())) must have the same value_type as this expected}}
126126
}
127127
}

0 commit comments

Comments
 (0)