There are a lot of code paths that (reasonably) do not expect a variable to disappear while being expanded/assigned to, and usually cause a segfault if that happens (as is now possible with the new nofork command substitution).
I don't think there is any legitimate use case to be supported here, and I can't really think of a sensible way to avoid this without adding a bunch of overhead. Hypothetically, bash could perform another variable lookup to confirm after expanding the other words in the PE, but this might have to deal with issues like array types changing when a new variable is brought into scope, etc. A similar situation is already ignored in mapfile's callback (which can unset the array being populated) and it seems fine to me to ignore these too, but posting in case others have better ideas. a=(x); a=(${ unset a; }) heap-use-after-free arrayfunc.c:667 in assign_compound_array_list a=(x); : ${a[${ unset a; }]} heap-use-after-free arrayfunc.c:1499 in array_value_internal a=(x); : ${#a[${ unset a; }]} heap-use-after-free subst.c:7378 in array_length_reference a=(x); : ${a[@]/${ unset a; }} heap-use-after-free subst.c:9331 in parameter_brace_patsub a=(x); : ${a[@]:${ unset a; }} heap-use-after-free subst.c:8305:11 in verify_substring_values a=(x); : ${a[@]:0:${ unset a; }} heap-use-after-free subst.c:8964:16 in parameter_brace_substring declare -A A; A=(x ${ unset A; }) heap-use-after-free variables.c:2859:36 in make_variable_value