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.
This error indicates that a constant references itself.
All constants need to resolve to a value in an acyclic manner.
For example, neither of the following can be sensibly compiled:
```
const X: u32 = X;
```
```
const X: u32 = Y;
const Y: u32 = X;
```
This commit is an implementation of [RFC 1044][rfc] which adds additional
surface area to the `std::fs` module. All new APIs are `#[unstable]` behind
assorted feature names for each one.
[rfc]: https://github.com/rust-lang/rfcs/pull/1044
The new APIs added are:
* `fs::canonicalize` - bindings to `realpath` on unix and
`GetFinalPathNameByHandle` on windows.
* `fs::symlink_metadata` - similar to `lstat` on unix
* `fs::FileType` and accessor methods as `is_{file,dir,symlink}`
* `fs::Metadata::file_type` - accessor for the raw file type
* `fs::DirEntry::metadata` - acquisition of metadata which is free on Windows
but requires a syscall on unix.
* `fs::DirEntry::file_type` - access the file type which may not require a
syscall on most platforms.
* `fs::DirEntry::file_name` - access just the file name without leading
components.
* `fs::PathExt::symlink_metadata` - convenience method for the top-level
function.
* `fs::PathExt::canonicalize` - convenience method for the top-level
function.
* `fs::PathExt::read_link` - convenience method for the top-level
function.
* `fs::PathExt::read_dir` - convenience method for the top-level
function.
* `std::os::raw` - type definitions for raw OS/C types available on all
platforms.
* `std::os::$platform` - new modules have been added for all currently supported
platforms (e.g. those more specific than just `unix`).
* `std::os::$platform::raw` - platform-specific type definitions. These modules
are populated with the bare essentials necessary for lowing I/O types into
their raw representations, and currently largely consist of the `stat`
definition for unix platforms.
This commit also deprecates `Metadata::{modified, accessed}` in favor of
inspecting the raw representations via the lowering methods of `Metadata`.
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 adds a new `#[cfg]` matcher against the `target_env` property of the
destination target triple. For example all windows triples today end with `-gnu`
but we will also hopefully support non-`gnu` targets for Windows, at which point
we'll need to differentiate between the two. This new `target_env` matches is
provided and filled in with the target's environment name.
Currently the only non-empty value of this name is `gnu`, but `musl` will be
shortly added for the linux triples.
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).**
Rather than storing the relations between free-regions in a global
table, introduce a `FreeRegionMap` data structure. regionck computes the
`FreeRegionMap` for each fn and stores the result into the tcx so that
borrowck can use it (this could perhaps be refactored to have borrowck
recompute the map, but it's a bid tedious to recompute due to the
interaction of closures and free fns). The main reason to do this is
because of #22779 -- using a global table was incorrect because when
validating impl method signatures, we want to use the free region
relationships from the *trait*, not the impl.
Fixes#22779.
Changes the style guidelines regarding unit tests to recommend using a
sub-module named "tests" instead of "test" for unit tests as "test"
might clash with imports of libtest.
skolemize_late_bound_regions essentially copies the entire type (most of the times it shouldn't, but it does), and match_impl runs millions of times.
Times compiling rustc, tested with
$ make -j4 rustc-stage1
$ ( time RUSTFLAGS=-Z time-passes make -j4 rustc-stage2 ) # need LLVM time for calibration
Before:
real 21m44.960s
user 29m38.812s
sys 0m14.944s
After:
real 19m31.445s
user 26m47.260s
sys 0m14.952s
Making this is a 10% performance improvement.
LLVM passes took 867 seconds before, 862 seconds after.
For now, words() is left in (but deprecated), and Words is a type alias for
struct SplitWhitespace.
Also cleaned up references to str.words() throughout codebase.
Closes#15628
When linking an archive statically to an rlib, the compiler will extract all
contents of the archive and add them all to the rlib being generated. The
current method of extraction is to run `ar x`, dumping all files into a
temporary directory. Object archives, however, are allowed to have multiple
entries with the same file name, so there is no method for them to extract their
contents into a directory in a lossless fashion.
This commit adds iterator support to the `ArchiveRO` structure which hooks into
LLVM's support for reading object archives. This iterator is then used to
inspect each object in turn and extract it to a unique location for later
assembly.
For now, words() is left in (but deprecated), and Words is a type alias for
struct SplitWhitespace.
Also cleaned up references to s.words() throughout codebase.
Closes#15628
This commit removes all the old casting/generic traits from `std::num` that are
no longer in use by the standard library. This additionally removes the old
`strconv` module which has not seen much use in quite a long time. All generic
functionality has been supplanted with traits in the `num` crate and the
`strconv` module is supplanted with the [rust-strconv crate][rust-strconv].
[rust-strconv]: https://github.com/lifthrasiir/rust-strconv
This is a breaking change due to the removal of these deprecated crates, and the
alternative crates are listed above.
[breaking-change]
When linking an archive statically to an rlib, the compiler will extract all
contents of the archive and add them all to the rlib being generated. The
current method of extraction is to run `ar x`, dumping all files into a
temporary directory. Object archives, however, are allowed to have multiple
entries with the same file name, so there is no method for them to extract their
contents into a directory in a lossless fashion.
This commit adds iterator support to the `ArchiveRO` structure which hooks into
LLVM's support for reading object archives. This iterator is then used to
inspect each object in turn and extract it to a unique location for later
assembly.
Note: this Warns rather than error on shadowing problems involving labels.
We took this more conservative option mostly due to issues with
hygiene being broken for labels and/or lifetimes.
Add FIXME regarding non-hygienic comparison.
skolemize_late_bound_regions essentially copies the entire type (most of the times it shouldn't, but it does), and match_impl runs millions of times.
Times compiling rustc, tested with
$ make -j4 rustc-stage1
$ ( time RUSTFLAGS=-Z time-passes make -j4 rustc-stage2 ) # need LLVM time for calibration
Before:
real 21m44.960s
user 29m38.812s
sys 0m14.944s
After:
real 19m31.445s
user 26m47.260s
sys 0m14.952s
Making this is a 10% performance improvement.
LLVM passes took 867 seconds before, 862 seconds after.
I did a manual merge of all the extended error PRs as we were getting merge conflicts yesterday. I think this is preferable to merging separately as I ended up having to manually merge @nham and @GuillaumeGomez's commits.
Rollup of #24458, #24482 and #24488.
#24482 and #24488 were already re-approved, and would need to be cancelled if this is merged instead.
table, introduce a `FreeRegionMap` data structure. regionck computes the
`FreeRegionMap` for each fn and stores the result into the tcx so that
borrowck can use it (this could perhaps be refactored to have borrowck
recompute the map, but it's a bid tedious to recompute due to the
interaction of closures and free fns). The main reason to do this is
because of #22779 -- using a global table was incorrect because when
validating impl method signatures, we want to use the free region
relationships from the *trait*, not the impl.
Fixes#22779.
I'm on a quest to slowly refactor a lot of the inference code. A first step for that is moving the "pure data structures" out so as to simplify what's left. This PR moves `snapshot_vec`, `graph`, and `unify` into their own crate (`librustc_data_structures`). They can then be unit-tested, benchmarked, etc more easily. As a benefit, I improved the performance of unification slightly on the benchmark I added vs the original code.
r? @nrc