This commit is an implementation of [RFC 1721] which adds a new target feature
to the compiler, `crt-static`, which can be used to select how the C runtime for
a target is linked. Most targets dynamically linke the C runtime by default with
the notable exception of some of the musl targets.
[RFC 1721]: https://github.com/rust-lang/rfcs/blob/master/text/1721-crt-static.md
This commit first adds the new target-feature, `crt-static`. If enabled, then
the `cfg(target_feature = "crt-static")` will be available. Targets like musl
will have this enabled by default. This feature can be controlled through the
standard target-feature interface, `-C target-feature=+crt-static` or
`-C target-feature=-crt-static`.
Next this adds an gated and unstable `#[link(cfg(..))]` feature to enable the
`crt-static` semantics we want with libc. The exact behavior of this attribute
is a little squishy, but it's intended to be a forever-unstable
implementation detail of the liblibc crate.
Specifically the `#[link(cfg(..))]` annotation means that the `#[link]`
directive is only active in a compilation unit if that `cfg` value is satisfied.
For example when compiling an rlib, these directives are just encoded and
ignored for dylibs, and all staticlibs are continued to be put into the rlib as
usual. When placing that rlib into a staticlib, executable, or dylib, however,
the `cfg` is evaluated *as if it were defined in the final artifact* and the
library is decided to be linked or not.
Essentially, what'll happen is:
* On MSVC with `-C target-feature=-crt-static`, the `msvcrt.lib` library will be
linked to.
* On MSVC with `-C target-feature=+crt-static`, the `libcmt.lib` library will be
linked to.
* On musl with `-C target-feature=-crt-static`, the object files in liblibc.rlib
are removed and `-lc` is passed instead.
* On musl with `-C target-feature=+crt-static`, the object files in liblibc.rlib
are used and `-lc` is not passed.
This commit does **not** include an update to the liblibc module to implement
these changes. I plan to do that just after the 1.14.0 beta release is cut to
ensure we get ample time to test this feature.
cc #37406
rustbuild: Tweak default rule inclusion
If a rule is flagged with `default(true)` then the pseudo-rule `default:foo`
will include that. If a rule is also flagged with `.host(true)`, however, then
the rule shouldn't be included for targets that aren't in the host array. This
adds a filter to ensure we don't pull in host rules for targets by accident.
test: Move missing-items to a ui test
This test is failing on nightly for unknown reasons, and my best guess is a
difference in grep versions which is interpreting symbols differently. For now
let's just move this to a ui test and hope it fixes nightlies.
If a rule is flagged with `default(true)` then the pseudo-rule `default:foo`
will include that. If a rule is also flagged with `.host(true)`, however, then
the rule shouldn't be included for targets that aren't in the host array. This
adds a filter to ensure we don't pull in host rules for targets by accident.
Restore Vec::from_iter() specialization
Since I said "no intentional functional change" in the previous commit,
I guess it was inevitable there were unintentional changes. Not
functional, but optimization-wise. This restores the extend
specialization's use in Vec::from_iter. (commit 1).
Also use specialization in from_iter to reduce allocation code duplication
for the TrustedLen case (commit 2).
Bug introduced in PR #37709
This test is failing on nightly for unknown reasons, and my best guess is a
difference in grep versions which is interpreting symbols differently. For now
let's just move this to a ui test and hope it fixes nightlies.
Fix syntax error in the compiler
Currently `rustc` accepts the following code: `fn f<'a>() where 'a {}`. This should be a syntax error, shouldn't it?
Not sure if my changes actually compile, waiting for the LLVM to build.
trans: Make type names in LLVM IR independent of crate-nums and source locations.
UPDATE:
This PR makes the type names we assign in LLVM IR independent of the type definition's location in the source code and the order in which extern crates are loaded. The new type names look like the old ones, except for closures and the `<crate-num>.` prefix being gone. Resolution of name clashes (e.g. of the same type in different crate versions) is left to LLVM (which will just append `.<counter>` to the name).
ORIGINAL TEXT:
This PR makes the type names we assign in LLVM IR independent of the type definition's location in the source code. Before, the type of closures contained the closures definition location. The new naming scheme follows the same pattern that we already use for symbol names: We have a human readable prefix followed by a hash that makes sure we don't have any collisions. Here is an example of what the new names look like:
```rust
// prog.rs - example program
mod mod1
{
pub struct Struct<T>(pub T);
}
fn main() {
use mod1::Struct;
let _s = Struct(0u32);
let _t = Struct('h');
let _x = Struct(Struct(0i32));
}
```
Old:
```llvm
%"mod1::Struct<u32>" = type { i32 }
%"mod1::Struct<char>" = type { i32 }
%"mod1::Struct<mod1::Struct<i32>>" = type { %"mod1::Struct<i32>" }
%"mod1::Struct<i32>" = type { i32 }
```
New:
```llvm
%"prog::mod1::Struct<u32>::ejDrT" = type { i32 }
%"prog::mod1::Struct<char>::2eEAU" = type { i32 }
%"prog::mod1::Struct<prog::mod1::Struct<i32>>::ehCqR" = type { %"prog::mod1::Struct<i32>::$fAo2" }
%"prog::mod1::Struct<i32>::$fAo2" = type { i32 }
```
As you can see, the new names are slightly more verbose, but also more consistent. There is no difference now between a local type and one from another crate (before, non-local types where prefixed with `<crate-num>.` as in `2.std::mod1::Type1`).
There is a bit of design space here. For example, we could leave off the crate name for local definitions (making names shorter but less consistent):
```llvm
%"mod1::Struct<u32>::ejDrT" = type { i32 }
%"mod1::Struct<char>::2eEAU" = type { i32 }
%"mod1::Struct<mod1::Struct<i32>>::ehCqR" = type { %"mod1::Struct<i32>::$fAo2" }
%"mod1::Struct<i32>::$fAo2" = type { i32 }
```
We could also put the hash in front, which might be more readable:
```llvm
%"ejDrT.mod1::Struct<u32>" = type { i32 }
%"2eEAU.mod1::Struct<char>" = type { i32 }
%"ehCqR.mod1::Struct<mod1::Struct<i32>>" = type { %"$fAo2.mod1::Struct<i32>" }
%"$fAo2.mod1::Struct<i32>" = type { i32 }
```
We could probably also get rid of the hash if we used full DefPaths and crate-nums (though I'm not yet a 100% sure if crate-nums could mess with incremental compilation).
```llvm
%"mod1::Struct<u32>" = type { i32 }
%"mod1::Struct<char>" = type { i32 }
%"mod1::Struct<mod1::Struct<i32>>" = type { %"mod1::Struct<i32>" }
%"mod1::Struct<i32>" = type { i32 }
%"2.std::mod1::Type1" = type { ... }
```
I would prefer the solution with the hashes because it is nice and consistent conceptually, but visually it's admittedly a bit uglier. Maybe @rust-lang/compiler would like to bikeshed a little about this.
On a related note: Has anyone ever tried if the LTO-linker will merge equal types with different names?
(^ @brson, @alexcrichton ^)
If not, that would be a reason to make type names more consistent.
Before this PR, type names could depend on the cratenum being used
for a given crate and also on the source location of closures.
Both are undesirable for incremental compilation where we cache
LLVM IR and don't want it to depend on formatting or in which
order crates are loaded.
Macro parser performance improvements and refactoring
This PR locally increased performance of https://github.com/rust-lang/rust/issues/37074 by ~6.6 minutes.
Follow up to https://github.com/rust-lang/rust/pull/37569, but doesn't focus explicitly on expansion performance.
History is relatively clean, but I can/will do some more polishing if this is deemed mergeable. Partially posting this now so I can get Travis to run tests for me.
r? @jseyfried
Vec::from_iter's general case allocates the vector up front;
this is redundant for the TrustedLen case, and can then be avoided
to reduce the size of the code.
Translate closures through the collector
Now that old trans is gone, there is no need for the hack of translating closures when they are instantiated. We can translate them like regular items.
r? @eddyb
Since I said "no intentional functional change" in the previous commit,
I guess it was inevitable there were unintentional changes. Not
functional, but optimization-wise. This restores the extend
specialization's use in Vec::from_iter.
to let people experiment with this target out of tree.
The MSP430 architecture is used in 16-bit microcontrollers commonly used
in Digital Signal Processing applications.
compile-test: allow overriding nodejs binary location
Add a command-line argument to manually specify which nodejs binary should be used,
which disables the default search.
Original work done by @tari.
Fixes#34188.