I've been working on improving the diagnostic registration system so that it can:
* Check uniqueness of error codes *across the whole compiler*. The current method using `errorck.py` is prone to failure as it relies on simple text search - I found that it breaks when referencing an error's ident within a string (e.g. `"See also E0303"`).
* Provide JSON output of error metadata, to eventually facilitate HTML output, as well as tracking of which errors need descriptions. The current schema is:
```
<error code>: {
"description": <long description>,
"use_site": {
"filename": <filename where error is used>,
"line": <line in file where error is used>
}
}
```
[Here's][metadata-dump] a pretty-printed sample dump for `librustc`.
One thing to note is that I had to move the diagnostics arrays out of the diagnostics modules. I really wanted to be able to capture error usage information, which only becomes available as a crate is compiled. Hence all invocations of `__build_diagnostics_array!` have been moved to the ends of their respective `lib.rs` files. I tried to avoid moving the array by making a plugin that expands to nothing but couldn't invoke it in item position and gave up on hackily generating a fake item. I also briefly considered using a lint, but it seemed like it would impossible to get access to the data stored in the thread-local storage.
The next step will be to generate a web page that lists each error with its rendered description and use site. Simple mapping and filtering of the metadata files also allows us to work out which error numbers are absent, which errors are unused and which need descriptions.
[metadata-dump]: https://gist.github.com/michaelsproul/3246846ff1bea71bd049
This is OK to do given:
- PIE is supported on Android starting with API 16.
- The bots are running API 18.
- API < 16 now has a 12.5% market share[0] as of 2015-04-29.
Closes#17437.
[0] https://developer.android.com/about/dashboards/index.html
r? @alexcrichton
Add `-g` (to testcase) that I should have included in PR #24932.
Note it is safe, with respect to autobuilds, to land before #24945.
(In other words, landing this sooner won't break things for anyone any
worse than they were already broken, since there are *other* tests
that also add `-g` to their flags via `compile-flags: -g`.)
Fixes for -g handling
First:
* decouples our handling of `-g` for the test suite from our handling of `-g` for the rest of the compiler/stdlib building.
* Namely, if you do `--enable-debug` or `--enable-debuginfo`, that should only affect `rustc` and the standard library crates; the tests should all continue to compile without `-g` unless:
* you pass `--enable-debuginfo-tests`, or
* the test itself requests the `-g` option (e.g. via a `// compile-flags: -g` embedded comment).
Second:
* Makes `rustc` more flexible in that it now accepts multiple occurrences of `-g -g`
* (as a drive-by, I gave `-O` the same treatment: multiple occurrences of `-O` are treated as synonymous as a single occurrence of `-O`.
Fix#24937
Currently, LLVM lowers a cttz8 on x86_64 to these instructions:
```asm
movzbl %dil, %eax
bsfl %eax, %eax
movl $32, %ecx
cmovnel %eax, %ecx
cmpl $32, %ecx
movl $8, %eax
cmovnel %ecx, %eax
```
To improve the codegen, we can zero extend the 8 bit integer, then set
bit 8 and perform a cttz operation on the extended value. That way
there's no conditional operation involved at all.
This was discovered by this benchmark: https://github.com/Kimundi/long_strings_without_repeats
Timings on my box with the current nightly:
```
running 4 tests
test bench_cpp_naive_big ... bench: 5479222 ns/iter (+/- 254222)
test bench_noop_big ... bench: 571405 ns/iter (+/- 111950)
test bench_rust_naive_big ... bench: 7798102 ns/iter (+/- 148841)
test bench_rust_unsafe_big ... bench: 6606488 ns/iter (+/- 67529)
```
Timings with the patch applied:
```
running 4 tests
test bench_cpp_naive_big ... bench: 5470944 ns/iter (+/- 7109)
test bench_noop_big ... bench: 568944 ns/iter (+/- 6895)
test bench_rust_naive_big ... bench: 6795901 ns/iter (+/- 43806)
test bench_rust_unsafe_big ... bench: 5584879 ns/iter (+/- 5291)
```
This is OK to do given:
- PIE is supported on Android starting with API 16.
- The bots are running API 18.
- API < 16 now has a 12.5% market share[0] as of 2015-04-29.
Unfortunately, this breaks backtrace support. See #17520.
Closes#17437.
[0] https://developer.android.com/about/dashboards/index.html
Note it is safe, with respect to autobuilds, to land before #24945.
(In other words, landing this sooner won't break things for anyone any
worse than they were already broken, since there are *other* tests
that also add `-g` to their flags via `compile-flags: -g`.)
metdata: Fix zero-normalization of the pos of a `MultiByteChar`
Fix#24687
The source byte/character mappings for every crate track the collection of multi-characters from its source files specially. When we import the source information for another file into the current compilation unit, we assign its byte-positions unique values by shifting them all by a fixed adjustment, tracked in the `start_pos` field. But when we pull out the source span information for one function from one crate and into our own crate, we need to re-normalize the byte positions: subtracting the old `start_pos` and adding the new `start_pos`. The `new_imported_filemap(..)` method handles adding the new `start_pos`, so all `creader` needs to do is re-normalize each `pos` to zero.
It seems like it was indeed trying to do this, but it mistakenly added the old `start_pos` instead of subtracting it.
There are still quite a few ignored Android tests kicking around, most of which were added in 445faca844, which has a pretty unfortunate commit message.
r? @alexcrichton
Implement Vec::drain(\<range type\>) from rust-lang/rfcs#574, tracking issue #23055.
This is a big step forward for vector usability. This is an introduction of an API for removing a range of *m* consecutive elements from a vector, as efficently as possible.
New features:
- Introduce trait `std::collections::range::RangeArgument` implemented by all four built-in range types.
- Change `Vec::drain()` to use `Vec::drain<R: RangeArgument>(R)`
Implementation notes:
- Use @Gankro's idea for memory safety: Use `set_len` on the source vector when creating the iterator, to make sure that the part of the vector that will be modified is unreachable. Fix up things in Drain's destructor — but even if it doesn't run, we don't expose any moved-out-from slots of the vector.
- This `.drain<R>(R)` very close to how it is specified in the RFC.
- Introduced as unstable
- Drain reuses the slice iterator — copying and pasting the same iterator pointer arithmetic again felt very bad
- The `usize` index as a range argument in the RFC is not included. The ranges trait would have to change to accomodate it.
Please help me with:
- Name and location of the new ranges trait.
- Design of the ranges trait
- Understanding Niko's comments about variance (Note: for a long time I was using a straight up &mut Vec in the iterator, but I changed this to permit reusing the slice iterator).
Previous PR and discussion: #23071
These commits build on [some great work on reddit](http://www.reddit.com/r/rust/comments/33boew/weekend_experiment_link_rust_programs_against/) for adding MUSL support to the compiler. This goal of this PR is to enable a `--target x86_64-unknown-linux-musl` argument to the compiler to work A-OK. The outcome here is that there are 0 compile-time dependencies for a MUSL-targeting build *except for a linker*. Currently this also assumes that MUSL is being used for statically linked binaries so there is no support for dynamically linked binaries with MUSL.
MUSL support largely just entailed munging around with the linker and where libs are located, and the major highlights are:
* The entirety of `libc.a` is included in `liblibc.rlib` (statically included as an archive).
* The entirety of `libunwind.a` is included in `libstd.rlib` (like with liblibc).
* The target specification for MUSL passes a number of ... flavorful options! Each option is documented in the relevant commit.
* The entire test suite currently passes with MUSL as a target, except for:
* Dynamic linking tests are all ignored as it's not supported with MUSL
* Stack overflow detection is not working MUSL yet (I'm not sure why)
* There is a language change included in this PR to add a `target_env` `#[cfg]` directive. This is used to conditionally build code for only MUSL (or for linux distros not MUSL). I highly suspect that this will also be used by Windows to target MSVC instead of a MinGW-based toolchain.
To build a compiler targeting MUSL you need to follow these steps:
1. Clone the current MUSL repo from `git://git.musl-libc.org/musl`. Build this as usual and install it.
2. Clone and build LLVM's [libcxxabi](http://libcxxabi.llvm.org/) library. Only the `libunwind.a` artifact is needed. I have tried using upstream libunwind's source repo but I have not gotten unwinding to work with it unfortunately. Move `libunwind.a` adjacent to MUSL's `libc.a`
3. Configure a Rust checkout with `--target=x86_64-unknown-linux-musl --musl-root=$MUSL_ROOT` where `MUSL_ROOT` is where you installed MUSL in step 1.
I hope to improve building a copy of libunwind as it's still a little sketchy and difficult to do today, but other than that everything should "just work"! This PR is not intended to include 100% comprehensive support for MUSL, as future modifications will probably be necessary.
There were a few test cases to fix:
* Dynamic libraries are not supported with MUSL right now, so all of those
related test which force or require dylibs are ignored.
* Looks like the default stack for MUSL is smaller than glibc, so a few stack
allocations in benchmarks were boxed up (shouldn't have a perf impact).
* Some small linkage tweaks here and there
* Out-of-stack detection does not currently work with MUSL
Inspecting the current thread's info may not always work due to the TLS value
having been destroyed (or is actively being destroyed). The code for printing
a panic message assumed, however, that it could acquire the thread's name
through this method.
Instead this commit propagates the `Option` outwards to allow the
`std::panicking` module to handle the case where the current thread isn't
present.
While it solves the immediate issue of #24313, there is still another underlying
issue of panicking destructors in thread locals will abort the process.
Closes#24313
Inspecting the current thread's info may not always work due to the TLS value
having been destroyed (or is actively being destroyed). The code for printing
a panic message assumed, however, that it could acquire the thread's name
through this method.
Instead this commit propagates the `Option` outwards to allow the
`std::panicking` module to handle the case where the current thread isn't
present.
While it solves the immediate issue of #24313, there is still another underlying
issue of panicking destructors in thread locals will abort the process.
Closes#24313
Inspect enum discriminant *after* calling its destructor
Includes some drive-by cleanup (e.g. changed some field and method names to reflect fill-on-drop; added comments about zero-variant enums being classified as `_match::Single`).
Probably the most invasive change was the expansion of the maps `available_drop_glues` and `drop_glues` to now hold two different kinds of drop glues; there is the (old) normal drop glue, and there is (new) drop-contents glue that jumps straight to dropping the contents of a struct or enum, skipping its destructor.
* For all types that do not have user-defined Drop implementations, the normal glue is generated as usual (i.e. recursively dropping the fields of the data structure).
(And this actually is exactly what the newly-added drop-contents glue does as well.)
* For types that have user-defined Drop implementations, the "normal" drop glue now schedules a cleanup before invoking the `Drop::drop` method that will call the drop-contents glue after that invocation returns.
Fix#23611.
----
Is this a breaking change? The prior behavior was totally unsound, and it seems unreasonable that anyone was actually relying on it.
Nonetheless, since there is a user-visible change to the language semantics, I guess I will conservatively mark this as a:
[breaking-change]
(To see an example of what sort of user-visible change this causes, see the comments in the regression test.)
Closes#17841.
The majority of the work should be done, e.g. trait and inherent impls, different forms of UFCS syntax, defaults, and cross-crate usage. It's probably enough to replace the constants in `f32`, `i8`, and so on, or close to good enough.
There is still some significant functionality missing from this commit:
- ~~Associated consts can't be used in match patterns at all. This is simply because I haven't updated the relevant bits in the parser or `resolve`, but it's *probably* not hard to get working.~~
- Since you can't select an impl for trait-associated consts until partway through type-checking, there are some problems with code that assumes that you can check constants earlier. Associated consts that are not in inherent impls cause ICEs if you try to use them in array sizes or match ranges. For similar reasons, `check_static_recursion` doesn't check them properly, so the stack goes ka-blooey if you use an associated constant that's recursively defined. That's a bit trickier to solve; I'm not entirely sure what the best approach is yet.
- Dealing with consts associated with type parameters will raise some new issues (e.g. if you have a `T: Int` type parameter and want to use `<T>::ZERO`). See rust-lang/rfcs#865.
- ~~Unused associated consts don't seem to trigger the `dead_code` lint when they should. Probably easy to fix.~~
Also, this is the first time I've been spelunking in rustc to such a large extent, so I've probably done some silly things in a couple of places.
This changes the `ToTokens` implementations for expressions, statements, etc. with almost-trivial ones that produce `Interpolated(*Nt(...))` pseudo-tokens. In this way, quasiquote now works the same way as macros do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves pretty-printing at all, which removes the need for the `encode_with_hygiene` hack. All associated machinery is removed.
New `Nonterminal`s are added: NtArm, NtImplItem, and NtTraitItem. These are just for quasiquote, not macros.
`ToTokens` is no longer implemented for `Arg` (although this could be added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of `ToTokens` to turn AST fragments back into inspectable token trees. For this reason, this closes#16987.
As such, this is a [breaking-change].
Fixes#16472.
Fixes#15962.
Fixes#17397.
Fixes#16617.
An actual typeck error is the cause of many failed compilations but an
unrelated bug is being reported instead. It is triggered because a typeck
error is presumably not yet identified during compiler execution, which
would normally bypass an invariant in the presence of other errors. In
this particular situation, we delay the reporting of the bug until
abort_if_errors().
Closes#23827, closes#24356, closes#23041, closes#22897, closes#23966,
closes#24013, and closes#23729
**There is at least one situation where this bug may still be genuinely
triggered (#23437).**
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes#16987.
As such, this is a [breaking-change].
Fixes#16472.
Fixes#15962.
Fixes#17397.
Fixes#16617.