On Fri, 5 Apr 2024 08:15:20 -0400 June Choe <jchoe...@gmail.com> wrote:
> When assigning a list to an out of bounds index (ex: the next, n+1 > index), it errors the same but now changes the values of the vector > to NULL: > > ``` > x <- expression(a,b,c) > x[[4]] <- list() # Error > x > #> expression(NULL, NULL, NULL) > ``` > > Curiously, this behavior disappears if a prior attempt is made at > assigning to the same index, using a different incompatible object > that does not share this bug (like a function) Here's how the problem happens: 1. The call lands in src/main/subassign.c, do_subassign2_dflt(). 2. do_subassign2_dflt() calls SubassignTypeFix() to prepare the operand for the assignment. 3. Since the assignment is "stretching", SubassignTypeFix() calls EnlargeVector() to provide the space for the assignment. The bug relies on `x` not being IS_GROWABLE(), which may explain why a plain x[[4]] <- list() sometimes doesn't fail. The future assignment result `x` is now expression(a, b, c, NULL), and the old `x` set to expression(NULL, NULL, NULL) by SET_VECTOR_ELT(newx, i, VECTOR_ELT(x, i)); CLEAR_VECTOR_ELT(x, i); during EnlargeVector(). 4. But then the assignment fails, raising the error back in do_subassign2_dflt(), because the assignment kind is invalid: there is no way to put data.frames into an expression vector. The new resized `x` is lost, and the old overwritten `x` stays there. Not sure what the right way to fix this is. It's desirable to avoid shallow_duplicate(x) for the overwriting assignments, but then the sub-assignment must either succeed or leave the operand untouched. Is there a way to perform the type check before overwriting the operand? -- Best regards, Ivan ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel