[libcxx-commits] [libcxx] [libc++] Mark std::expected as nodiscard (PR #139651)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Apr 19 22:08:39 PDT 2026


https://github.com/halbi2 updated https://github.com/llvm/llvm-project/pull/139651

>From 0940140e7784beb767a274f06b0a8588e3ef7c06 Mon Sep 17 00:00:00 2001
From: halbi2 <hehiralbi at gmail.com>
Date: Mon, 12 May 2025 20:57:00 -0400
Subject: [PATCH] [libc++] Mark std::expected as nodiscard

Fixes #130656
---
 libcxx/include/__expected/expected.h          |  4 +-
 .../expected.expected/nodiscard.verify.cpp    | 49 +++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 libcxx/test/libcxx/utilities/expected/expected.expected/nodiscard.verify.cpp

diff --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index 24ae33d4e3af8..d0007f18db655 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -447,7 +447,7 @@ class __expected_base {
 };
 
 template <class _Tp, class _Err>
-class expected : private __expected_base<_Tp, _Err> {
+class [[nodiscard]] expected : private __expected_base<_Tp, _Err> {
   static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v<remove_cv_t<_Tp>, in_place_t> &&
                     !is_same_v<remove_cv_t<_Tp>, unexpect_t> && !__is_std_unexpected<remove_cv_t<_Tp>>::value &&
                     __valid_std_unexpected<_Err>::value,
@@ -1375,7 +1375,7 @@ class __expected_void_base {
 
 template <class _Tp, class _Err>
   requires is_void_v<_Tp>
-class expected<_Tp, _Err> : private __expected_void_base<_Err> {
+class [[nodiscard]] expected<_Tp, _Err> : private __expected_void_base<_Err> {
   static_assert(__valid_std_unexpected<_Err>::value,
                 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a "
                 "valid argument for unexpected<E> is ill-formed");
diff --git a/libcxx/test/libcxx/utilities/expected/expected.expected/nodiscard.verify.cpp b/libcxx/test/libcxx/utilities/expected/expected.expected/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..e9a4183c5394b
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/expected/expected.expected/nodiscard.verify.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++23
+
+// <expected>
+
+// Test that ignoring std::expected generates [[nodiscard]] warnings.
+
+#include <expected>
+
+std::expected<int, int> returns_expected();
+std::expected<void, int> returns_expected_void();
+
+std::expected<int, int> and_then(int);
+std::expected<void, int> and_then_void();
+std::expected<int, int> or_else(int);
+std::expected<void, int> or_else_void(int);
+int transform(int);
+void transform_void();
+int transform_error(int);
+int transform_error_void(int);
+
+void test() {
+  returns_expected();      // expected-warning {{ignoring return value of type 'expected<int, int>'}}
+  returns_expected_void(); // expected-warning {{ignoring return value of type 'expected<void, int>'}}
+
+  returns_expected().and_then(and_then);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected_void().and_then(and_then_void);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected().or_else(or_else);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected_void().or_else(or_else_void);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected().transform(transform);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected_void().transform(transform_void);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected().transform_error(transform_error);
+      // expected-warning at -1 {{ignoring return value}}
+  returns_expected_void().transform_error(transform_error_void);
+      // expected-warning at -1 {{ignoring return value}}
+}



More information about the libcxx-commits mailing list