[libcxx-commits] [libcxx] 3891468 - [libc++] Avoid using **this in error messages for expected monadic operations (#84840)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 1 05:56:17 PDT 2024
Author: ZERO-N
Date: 2024-08-01T08:56:10-04:00
New Revision: 389146816711ef6d11e54726e8ea300bf9945dc3
URL: https://github.com/llvm/llvm-project/commit/389146816711ef6d11e54726e8ea300bf9945dc3
DIFF: https://github.com/llvm/llvm-project/commit/389146816711ef6d11e54726e8ea300bf9945dc3.diff
LOG: [libc++] Avoid using **this in error messages for expected monadic operations (#84840)
Instead of using **this in error messages for std::expected monadic
operations, use value(). As shown in LWG3969, **this can trigger
unintended ADL and while it's only an error message, we might as
well be ADL-correct there too.
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
Modified:
libcxx/include/__expected/expected.h
libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index f618b20603e60..e47ec2f28844b 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -918,9 +918,9 @@ class expected : private __expected_base<_Tp, _Err> {
requires is_constructible_v<_Err, _Err&>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & {
using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>;
- static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
+ static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
static_assert(is_same_v<typename _Up::error_type, _Err>,
- "The result of f(**this) must have the same error_type as this expected");
+ "The result of f(value()) must have the same error_type as this expected");
if (has_value()) {
return std::invoke(std::forward<_Func>(__f), this->__val());
}
@@ -931,9 +931,9 @@ class expected : private __expected_base<_Tp, _Err> {
requires is_constructible_v<_Err, const _Err&>
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& {
using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>;
- static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected");
+ static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected");
static_assert(is_same_v<typename _Up::error_type, _Err>,
- "The result of f(**this) must have the same error_type as this expected");
+ "The result of f(value()) must have the same error_type as this expected");
if (has_value()) {
return std::invoke(std::forward<_Func>(__f), this->__val());
}
@@ -945,9 +945,9 @@ class expected : private __expected_base<_Tp, _Err> {
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && {
using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>;
static_assert(
- __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
+ __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
static_assert(is_same_v<typename _Up::error_type, _Err>,
- "The result of f(std::move(**this)) must have the same error_type as this expected");
+ "The result of f(std::move(value())) must have the same error_type as this expected");
if (has_value()) {
return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
}
@@ -959,9 +959,9 @@ class expected : private __expected_base<_Tp, _Err> {
_LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& {
using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>;
static_assert(
- __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected");
+ __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected");
static_assert(is_same_v<typename _Up::error_type, _Err>,
- "The result of f(std::move(**this)) must have the same error_type as this expected");
+ "The result of f(std::move(value())) must have the same error_type as this expected");
if (has_value()) {
return std::invoke(std::forward<_Func>(__f), std::move(this->__val()));
}
diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp
index 8b3138fd73db3..c46ab633295c1 100644
--- a/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/and_then.mandates.verify.cpp
@@ -11,22 +11,22 @@
// Test the mandates
// template<class F> constexpr auto and_then(F&& f) &;
// Mandates:
-// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
// template<class F> constexpr auto and_then(F&& f) const &;
// Mandates:
-// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
// template<class F> constexpr auto and_then(F&& f) &&;
// Mandates:
-// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
// template<class F> constexpr auto and_then(F&& f) const &&;
// Mandates:
-// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(**this)>>
+// Let U be std::remove_cvref_t<std::invoke_result<F, decltype(value())>>
// U is a specialization of std::expected and std::is_same_v<U:error_type, E> is true
#include <expected>
@@ -52,7 +52,7 @@ void test() {
{
std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
}
@@ -61,7 +61,7 @@ void test() {
{
std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must have the same error_type as this expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
}
}
@@ -71,7 +71,7 @@ void test() {
{
const std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must be a specialization of std::expected}}
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
}
@@ -80,7 +80,7 @@ void test() {
{
const std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(**this) must have the same error_type as this expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(value()) must have the same error_type as this expected}}
}
}
@@ -91,7 +91,7 @@ void test() {
{
std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
}
@@ -100,7 +100,7 @@ void test() {
{
std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must have the same error_type as this expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
}
}
@@ -110,7 +110,7 @@ void test() {
{
const std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must be a specialization of std::expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must be a specialization of std::expected}}
// expected-error-re@*:* {{{{.*}}cannot be used prior to '::' because it has no members}}
// expected-error-re@*:* {{no matching constructor for initialization of{{.*}}}}
}
@@ -119,7 +119,7 @@ void test() {
{
const std::expected<int, int> f1(1);
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}}
- // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(**this)) must have the same error_type as this expected}}
+ // expected-error-re@*:* {{static assertion failed {{.*}}The result of f(std::move(value())) must have the same error_type as this expected}}
}
}
}
More information about the libcxx-commits
mailing list