rustpkg: Set exit codes properly and make tests take advantage of that

When I started writing the rustpkg tests, task failure didn't set the
exit code properly. But bblum's work from July fixed that. Hooray! I
just didn't know about it till now.

So, now rustpkg uses exit codes in a more conventional way, and some of
the tests are simpler.

The bigger issue will be to make task failure propagate the error message.
Right now, rustpkg does most of the work in separate tasks, which means if
a task fails, rustpkg can't distinguish between different types of failure
(see #3408)
have LLVM print type strings for us

Example:

    void ({ i64, %tydesc*, i8*, i8*, i8 }*, i64*, %"struct.std::fmt::Formatter[#1]"*)*

Before, we would print 20 levels deep due to recursion in the type
definition.
auto merge of #9799 : catamorphism/rust/rustpkg-exitcodes, r=catamorphism,metajack

r? @metajack When I started writing the rustpkg tests, task failure didn't set the
exit code properly. But bblum's work from July fixed that. Hooray! I
just didn't know about it till now.

So, now rustpkg uses exit codes in a more conventional way, and some of
the tests are simpler.

The bigger issue will be to make task failure propagate the error message.
Right now, rustpkg does most of the work in separate tasks, which means if
a task fails, rustpkg can't distinguish between different types of failure
(see #3408)
auto merge of #9815 : thestinger/rust/type, r=huonw

Example:

    void ({ i64, %tydesc*, i8*, i8*, i8 }*, i64*, %"struct.std::fmt::Formatter[#1]"*)*

Before, we would print 20 levels deep due to recursion in the type
definition.
rc: fix docstring
auto merge of #9825 : thestinger/rust/rc, r=thestinger