rustc: Fix passing errors from LLVM to rustc

Many of the instances of setting a global error variable ended up leaving a
dangling pointer into free'd memory. This changes the method of error
transmission to strdup any error and "relinquish ownership" to rustc when it
gets an error. The corresponding Rust code will then free the error as
necessary.

Closes #12865
rustc: Give a friendlier error when writing deps

When an error is encountered when writing dependencies, this presents a nicer
error rather than an ICE.

Closes #13517
rustc: Don't die when a crate id can't be inferred

The filestem of the desired output isn't necessarily a valid crate id, and
calling unwrap() will trigger an ICE in rustc. This tries a little harder to
infer a "valid crate id" from a crate, with an eventual fallback to a generic
crate id if alll else fails.

Closes #11107