So, I was looking to take the output of unzip -Z1 into an array and found this answer; their first option, using mapfile and process substitution WITH input redirection, works a charm.
But then I thought, "wait, process substitution," which creates a file descriptor from the stdout, "then use input redirection on that to put the contents into stdin?"
Is that not equivalent to just piping?
Apparently no. No it isn't.
Here I try to put the contents of ls into a variable, but using a pipe: à la ls | mapfile -t test
Nada.
But, if I follow that answer to a T: id est mapfile -t test < <(ls)
Voilà.
But why? diff can't tell the difference. At least between their content.

I couldn't find anything inherently special about < <(), other than it creates a file descriptor. Using that as a theory, I tried a HEREDOC, which makes a file descriptor too. It worked:
mapfile -t test2 << END && printf '%s ' "${test2[@]}"
this
is
an
array
END
But not if it's laundered through stdin via cat, try:
cat << END | mapfile -t test3 && printf '%s ' "${test3[@]}"
this
is
an
array
END
So, my questions.
That HEREDOC discovery/file descriptor theory shouldn't matter for mapfile as its manuals all say it uses "standard input", right?
If 'standard input' somehow means it has to be a fancier descriptor; why? Why is it unable to use a simple read-once input stream to generate the array?
And finally if both of those are answered/on the right track, why didn't the command fail when it expected an fd? You'll see my terminal has 0 printed a bunch (and we use && for the last examples), that's $? on my prompt, so there was no error reported by the builtin.
I tried this on Fedora 30 and RHEL 6, so I don't think it's a bug.