@@ -59,6 +59,7 @@ inline void assign(Tuple1&& x, Tuple2&& y, const char* name);
5959template <
6060 typename T, typename U,
6161 require_t <std::is_assignable<std::decay_t <T>&, std::decay_t <U>>>* = nullptr ,
62+ require_all_not_std_vector_t <T, U>* = nullptr ,
6263 math::require_all_not_tuple_t <T, U>* = nullptr >
6364inline void assign (T&& x, U&& y, const char * name) {
6465 internal::assign_impl (x, std::forward<U>(y), name);
@@ -776,15 +777,25 @@ inline void assign(Mat1&& x, Mat2&& y, const char* name, const Idx& row_idx,
776777 * @param[in] y rvalue variable
777778 * @param[in] name name of lvalue variable
778779 */
779- template <typename T, typename U, require_all_std_vector_t <T, U>* = nullptr ,
780- require_not_t <
781- std::is_assignable<std::decay_t <T>&, std::decay_t <U>>>* = nullptr >
780+ template <typename T, typename U, require_all_std_vector_t <T, U>* = nullptr >
782781inline void assign (T&& x, U&& y, const char * name) {
783782 if (unlikely (x.size () != 0 )) {
784783 stan::math::check_size_match (" assign array size" , name, x.size (),
785784 " right hand side" , y.size ());
786785 }
787- if (std::is_rvalue_reference<U&&>::value) {
786+
787+ if constexpr (std::is_assignable_v<std::decay_t <T>&, std::decay_t <U>>) {
788+ if (is_stan_scalar_v<value_type_t <T>> || x.size () == 0 ) {
789+ x = std::forward<U>(y);
790+ return ;
791+ }
792+ }
793+
794+ // If we've made it this far, we need x to have elements to assign to,
795+ // and we know this is either a no-op or x has size 0, which we treat as
796+ // a wildcard that can take any size.
797+ x.resize (y.size ());
798+ if constexpr (std::is_rvalue_reference_v<U&&>) {
788799 for (size_t i = 0 ; i < y.size (); ++i) {
789800 assign (x[i], std::move (y[i]), name);
790801 }
0 commit comments