gmock-actions: add support for move-only values to Return.

`Return(x)` can now be used directly with `WillOnce` (the only place it makes
sense in the type system), without using `ByMove`.

PiperOrigin-RevId: 448380066
Change-Id: Ia71cc60ccbc3b99720662731a2d309735a5ce7c8
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index df2effd..e5981f9 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -881,6 +881,17 @@
   template <typename U, typename... Args,
             typename = typename std::enable_if<conjunction<
                 // See the requirements documented on Return.
+                negation<std::is_same<void, U>>,  //
+                negation<std::is_reference<U>>,   //
+                std::is_convertible<R, U>,        //
+                std::is_move_constructible<U>>::value>::type>
+  operator OnceAction<U(Args...)>() && {  // NOLINT
+    return Impl<U>(std::move(value_));
+  }
+
+  template <typename U, typename... Args,
+            typename = typename std::enable_if<conjunction<
+                // See the requirements documented on Return.
                 negation<std::is_same<void, U>>,   //
                 negation<std::is_reference<U>>,    //
                 std::is_convertible<const R&, U>,  //
@@ -894,9 +905,17 @@
   template <typename U>
   class Impl final {
    public:
+    // The constructor used when the return value is allowed to move from the
+    // input value (i.e. we are converting to OnceAction).
+    explicit Impl(R&& input_value)
+        : state_(new State(std::move(input_value))) {}
+
+    // The constructor used when the return value is not allowed to move from
+    // the input value (i.e. we are converting to Action).
     explicit Impl(const R& input_value) : state_(new State(input_value)) {}
 
-    U operator()() const { return state_->value; }
+    U operator()() && { return std::move(state_->value); }
+    U operator()() const& { return state_->value; }
 
    private:
     // We put our state on the heap so that the compiler-generated copy/move
@@ -923,6 +942,18 @@
             // explicit constructor from R.
             value(ImplicitCast_<U>(internal::as_const(input_value))) {}
 
+      // As above, but for the case where we're moving from the ReturnAction
+      // object because it's being used as a OnceAction.
+      explicit State(R&& input_value_in)
+          : input_value(std::move(input_value_in)),
+            // For the same reason as above we make an implicit conversion to U
+            // before initializing the value.
+            //
+            // Unlike above we provide the input value as an rvalue to the
+            // implicit conversion because this is a OnceAction: it's fine if it
+            // wants to consume the input value.
+            value(ImplicitCast_<U>(std::move(input_value))) {}
+
       // A copy of the value originally provided by the user. We retain this in
       // addition to the value of the mock function's result type below in case
       // the latter is a reference-like type. See the std::string_view example
@@ -1740,18 +1771,19 @@
 
 // Creates an action that returns a value.
 //
-// R must be copy-constructible. The returned type can be used as an
-// Action<U(Args...)> for any type U where all of the following are true:
+// The returned type can be used with a mock function returning a non-void,
+// non-reference type U as follows:
 //
-//  *  U is not void.
-//  *  U is not a reference type. (Use ReturnRef instead.)
-//  *  U is copy-constructible.
-//  *  const R& is convertible to U.
+//  *  If R is convertible to U and U is move-constructible, then the action can
+//     be used with WillOnce.
 //
-// The Action<U(Args)...> object contains the R value from which the U return
-// value is constructed (a copy of the argument to Return). This means that the
-// R value will survive at least until the mock object's expectations are
-// cleared or the mock object is destroyed, meaning that U can be a
+//  *  If const R& is convertible to U and U is copy-constructible, then the
+//     action can be used with both WillOnce and WillRepeatedly.
+//
+// The mock expectation contains the R value from which the U return value is
+// constructed (a move/copy of the argument to Return). This means that the R
+// value will survive at least until the mock object's expectations are cleared
+// or the mock object is destroyed, meaning that U can safely be a
 // reference-like type such as std::string_view:
 //
 //     // The mock function returns a view of a copy of the string fed to
@@ -1794,6 +1826,8 @@
   return internal::ReturnRefOfCopyAction<R>(x);
 }
 
+// DEPRECATED: use Return(x) directly with WillOnce.
+//
 // Modifies the parent action (a Return() action) to perform a move of the
 // argument instead of a copy.
 // Return(ByMove()) actions can only be executed once and will assert this
diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc
index 414c615..9aa9f81 100644
--- a/googlemock/test/gmock-actions_test.cc
+++ b/googlemock/test/gmock-actions_test.cc
@@ -47,6 +47,7 @@
 #include "gmock/gmock-actions.h"
 
 #include <algorithm>
+#include <functional>
 #include <iterator>
 #include <memory>
 #include <string>
@@ -709,6 +710,24 @@
   EXPECT_THAT(mock.AsStdFunction()(), Field(&Out::x, 19));
 }
 
+// It should be possible to use Return(R) with a mock function result type U
+// that is convertible from const R& but *not* R (such as
+// std::reference_wrapper). This should work for both WillOnce and
+// WillRepeatedly.
+TEST(ReturnTest, ConversionRequiresConstLvalueReference) {
+  using R = int;
+  using U = std::reference_wrapper<const int>;
+
+  static_assert(std::is_convertible<const R&, U>::value, "");
+  static_assert(!std::is_convertible<R, U>::value, "");
+
+  MockFunction<U()> mock;
+  EXPECT_CALL(mock, Call).WillOnce(Return(17)).WillRepeatedly(Return(19));
+
+  EXPECT_EQ(17, mock.AsStdFunction()());
+  EXPECT_EQ(19, mock.AsStdFunction()());
+}
+
 // Return(x) should not be usable with a mock function result type that's
 // implicitly convertible from decltype(x) but requires a non-const lvalue
 // reference to the input. It doesn't make sense for the conversion operator to
@@ -731,32 +750,33 @@
 
   // It shouldn't be possible to use the result of Return(std::string) in a
   // context where an S is needed.
+  //
+  // Here too we disable the assertion for MSVC, since its incorrect
+  // implementation of is_convertible causes our SFINAE to be wrong.
   using RA = decltype(Return(std::string()));
 
   static_assert(!std::is_convertible<RA, Action<S()>>::value, "");
+#ifndef _MSC_VER
   static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
+#endif
 }
 
-// Return(x) should not be usable with a mock function result type that's
-// implicitly convertible from decltype(x) but requires an rvalue reference to
-// the input. We don't yet support handing over the value for consumption.
-TEST(ReturnTest, ConversionRequiresRvalueReference) {
-  // Set up a type that is implicitly convertible from std::string&& and
-  // `const std::string&&`, but not `const std::string&`.
-  struct S {
-    S(std::string&&) {}        // NOLINT
-    S(const std::string&&) {}  // NOLINT
-  };
+TEST(ReturnTest, MoveOnlyResultType) {
+  // Return should support move-only result types when used with WillOnce.
+  {
+    MockFunction<std::unique_ptr<int>()> mock;
+    EXPECT_CALL(mock, Call)
+        // NOLINTNEXTLINE
+        .WillOnce(Return(std::unique_ptr<int>(new int(17))));
 
-  static_assert(std::is_convertible<std::string, S>::value, "");
-  static_assert(!std::is_convertible<const std::string&, S>::value, "");
+    EXPECT_THAT(mock.AsStdFunction()(), Pointee(17));
+  }
 
-  // It shouldn't be possible to use the result of Return(std::string) in a
-  // context where an S is needed.
-  using RA = decltype(Return(std::string()));
-
-  static_assert(!std::is_convertible<RA, Action<S()>>::value, "");
-  static_assert(!std::is_convertible<RA, OnceAction<S()>>::value, "");
+  // The result of Return should not be convertible to Action (so it can't be
+  // used with WillRepeatedly).
+  static_assert(!std::is_convertible<decltype(Return(std::unique_ptr<int>())),
+                                     Action<std::unique_ptr<int>()>>::value,
+                "");
 }
 
 // Tests that Return(v) is covaraint.