The \line macro expects a length without a unit as it uses \unitlength (default: 1pt) for this parameter (as well to the argument of the picture environment which size you have set to 0pt × 0pt by the way).
Here are three and a fourth possible solution to deal with that. The first one just stripes the pt from \textwidth so that the picture environment can multiply it again with the \unitlength of 1pt.
The second one is similar to the first in that it sets \unitlength to \textwidth so that the \line macro can be used as \line(1,0){1}.
The third one goes one step further and sets \unitlength to \textwidth for the whole picture so that even its dimension can be given in \textwidth lengths.
The fourth solution simply uses the LaTeX macro \rule to mimic the output of your picture environment.
Code
\documentclass[12pt,a4paper]{article}
\usepackage[showframe,pass]{geometry}
\makeatletter
\def\strippt{\strip@pt}
\makeatother
\begin{document}
\noindent
\begin{picture}(\strippt\textwidth,0)%
\linethickness{1.5pt}%
\put(0,0){\line(1,0){\strippt\textwidth}}
\end{picture}
\noindent
\begin{picture}(\strippt\textwidth,0)%
\linethickness{1.5pt}%
\put(0,0){\setlength{\unitlength}{\textwidth}\line(1,0){1}}
\end{picture}
\noindent\begingroup\setlength{\unitlength}{\textwidth}%
\begin{picture}(1,0)%
\linethickness{1.5pt}%
\put(0,0){\line(1,0){1}}
\end{picture}
\endgroup
\noindent\rule[-.75pt]{\textwidth}{1.5pt}
\end{document}
Output

\linemacro does expects a length withoutpt, so you could use\strippt\textwidthinstead (with\stripptdefined as\makeatletter\def\strippt{\strip@pt}\makeatother). Though, in this case it would be easier to just use\rule{\textwidth}{1.5pt}. – Qrrbrbirlbel Apr 19 '13 at 02:02