diff --git a/NEWS.md b/NEWS.md index ecd9ad3928..190a926d36 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # dplyr (development version) +* Empty `rowwise()` list-column elements now resolve to `logical()` rather than a random logical of length 1 (#7710). + * `last_dplyr_warnings()` no longer prevents objects from being garbage collected (#7649). * Progress towards making dplyr conformant with the public C API of R (#7741). diff --git a/src/chop.cpp b/src/chop.cpp index a27bcfcd88..2b72fc3307 100644 --- a/src/chop.cpp +++ b/src/chop.cpp @@ -26,7 +26,7 @@ void dplyr_lazy_vec_chop_grouped(SEXP chops_env, SEXP rows, SEXP data, bool roww SET_VECTOR_ELT(column, 0, ptype); } else { // i.e. `vec_ptype_finalise(unspecified())` (#6369) - SET_VECTOR_ELT(column, 0, Rf_allocVector(LGLSXP, 1)); + SET_VECTOR_ELT(column, 0, Rf_allocVector(LGLSXP, 0)); } SET_PRCODE(prom, column); UNPROTECT(2); diff --git a/tests/testthat/test-mutate.R b/tests/testthat/test-mutate.R index 0bf70ab602..7a52570a16 100644 --- a/tests/testthat/test-mutate.R +++ b/tests/testthat/test-mutate.R @@ -332,6 +332,14 @@ test_that("mutate preserves class of zero-row rowwise (#4224, #6303)", { out <- mutate(rf, x2 = identity(x), x3 = x) expect_equal(out$x2, logical()) expect_equal(out$x3, logical()) + + # with the empty list case, `x` is `logical()`, not a random logical of length + # 1 that happens to get recycled to length 0 (#7710) + rf <- rowwise(tibble(x = list())) + out <- mutate(rf, x2 = { + expect_identical(x, logical()) + x + }) }) test_that("mutate works on empty data frames (#1142)", {