You have to know that _ (in math mode, of course, and with normal setting of category codes) will expand the next token in order to see if a brace (explicit or implicit) follows. This is common for primitives that want a <general text> as their argument (so also \uppercase, for instance).
Thus _ will try expanding the following token, because it's not { or \bgroup. The first level expansion of \text is
\protect\text•
(where • denotes a space in the name of the control sequence). Since we are in a normal situation (typesetting), \protect is equivalent to \relax. Here another feature comes in: when a <general text> is being looked for, spaces and \relax tokens are ignored (they're called a <filler> in the TeXbook), so this \protect disappears. Now \text• is not a brace, so TeX continues expanding it; the first level expansion is
\ifmmode\expandafter\text@\else\expandafter\mbox\fi
OK, we're in math mode, so we're left with
\expandafter\text@\else\expandafter\mbox\fi
Hmm, \expandafter is not a brace, expand it! This causes the expansion of \else, therefore just \text@ remains. Here we are, almost! The definition of \text@ in amstext.sty is
\def\text@#1{{\mathchoice
{\textdef@\displaystyle\f@size{#1}}%
{\textdef@\textstyle\f@size{\firstchoice@false #1}}%
{\textdef@\textstyle\sf@size{\firstchoice@false #1}}%
{\textdef@\textstyle \ssf@size{\firstchoice@false #1}}%
\check@mathfonts
}%
}
so, since TeX wants to expand it, the argument is looked for; y is a token which is not a brace that delimits an argument, so it is the argument.
The expansion is then
{\mathchoice...}
with y in place of #1. Hurray! The open brace has been found! Go on and typeset the subscript.
Final word: always use braces around the subscript and arguments; your input will be clearer. So
$x_{\text{y}}$
and nothing else.