Simplify a few functions in rustc_data_structures
- drop `try!()` where it's superfluous
- change `try!()` to `?`
- squash a `push` with `push_str`
- refactor a push loop into an iterator
[NLL] Fix some things for bootstrap
Some changes that are required when bootstrapping rustc with NLL enabled.
* Remove a bunch of unused `mut`s that aren't needed, but the existing lint doesn't catch.
* Rewrite a function call to satisfy NLL borrowck. Note that the borrow is two-phase, but gets activated immediately by an unsizing coercion.
cc #51823
Tweak the raw_identifiers lints in 2018
* Enable the `raw_identifiers` feature automatically in the 2018 preview
* Only emit lint warnings if the `raw_identifiers` feature is activated
cc rust-lang/cargo#5783
Don't format!() string literals
Prefer `to_string()` to `format!()` take 2, this time targetting string literals. In some cases (`&format!("...")` -> `"..."`) also removes allocations. Occurences of `format!("")` are changed to `String::new()`.
Replace push loops with extend() where possible
Or set the vector capacity where I couldn't do it.
According to my [simple benchmark](https://gist.github.com/ljedrz/568e97621b749849684c1da71c27dceb) `extend`ing a vector can be over **10 times** faster than `push`ing to it in a loop:
10 elements (6.1 times faster):
```
test bench_extension ... bench: 75 ns/iter (+/- 23)
test bench_push_loop ... bench: 458 ns/iter (+/- 142)
```
100 elements (11.12 times faster):
```
test bench_extension ... bench: 87 ns/iter (+/- 26)
test bench_push_loop ... bench: 968 ns/iter (+/- 3,528)
```
1000 elements (11.04 times faster):
```
test bench_extension ... bench: 311 ns/iter (+/- 9)
test bench_push_loop ... bench: 3,436 ns/iter (+/- 233)
```
Seems like a good idea to use `extend` as much as possible.
Do a basic sanity check for all constant values
## Motivation and high level overview
There has been some back and forth in this PR between @RalfJung and me in here about the motivation for this change and the stance it takes on unsafe coding guidelines.
The initial implementation ran its checks on every value read (so `*x`, `y = x`, ...). In unsafe code that isn't reasonable, because we might be invalidating invariants for a short time in order to build up a proper value.
The current implementation is a lint that runs its checks statics and constants. There is no need to check array lengths and enum variants, because it's a hard error to end up with anything but a number, and that one even has to have the required bits to be defined.
## What checks are done?
* Some type related checks
* `char` needs to be a correct unicode character as defined by `char::from_u32`
* A reference to a ZST must have the correct alignment (and be nonzero)
* A reference to anything is dereferenced and its value is checked
* Layout checks use the information from `ty::Layout` to check
* all fields of structs
* all elements of arrays
* enum discriminants
* the fields of an enum variant (the variant is decided by the discriminant)
* whether any union field succeeds in being checked (if none match the memory pattern, the check fails)
* if the value is in the range described by the layout (e.g. for `NonZero*` types)
Changing the layout of a type will thus automatically cause the checks to check for the new layout.
fixes#51330fixes#51471
cc @RalfJung
r? @eddyb