You can't use shell completion inside M-x shell. Emacs sends the input to the shell one line at a time when you press RET. When you press TAB, it's Emacs's built-in completion that's triggered. In shell mode, Emacs tries to keep track of your current directory and completes file names, but that's all.
Depending on what program you're interacting with, shell mode can be nice (because you get all of Emacs's edition features instead of whatever limited capabilities the shell or other program provides) or not so nice (because you don't get whatever nifty capabilities the shell or other program provides. When running zsh, you're in the latter category. Inside Emacs, you can run M-x term to run a more complete terminal emulator inside Emacs, where you interact directly with the underlying program. You gain some, but you also lose some: Term mode's scrollback capabilities are poor.
You can switch between Term mode and Shell mode in the same buffer. You must start the buffer in Term mode, then you can use these functions to toggle between the two. (Note: I didn't write these functions originally, it was contributed to the Emacs Wiki and I have not tracked down the source. I have slightly adapted it; warning: I haven't tested this code.)
(defun term-switch-to-shell-mode ()
(interactive)
(shell-mode)
(set-process-filter (get-buffer-process (current-buffer)) 'comint-output-filter )
(compilation-shell-minor-mode 1)
(comint-send-input))
(defun shell-switch-to-term-mode ()
(compilation-shell-minor-mode -1)
(font-lock-mode -1)
(set-process-filter (get-buffer-process (current-buffer)) 'term-emulate-terminal)
(term-mode)
(term-char-mode)
(term-send-raw-string (kbd "C-l")))