crate-ify compiler-rt into compiler-builtins
libcompiler-rt.a is dead, long live libcompiler-builtins.rlib
This commit moves the logic that used to build libcompiler-rt.a into a
compiler-builtins crate on top of the core crate and below the std crate.
This new crate still compiles the compiler-rt instrinsics using gcc-rs
but produces an .rlib instead of a static library.
Also, with this commit rustc no longer passes -lcompiler-rt to the
linker. This effectively makes the "no-compiler-rt" field of target
specifications a no-op. Users of `no_std` will have to explicitly add
the compiler-builtins crate to their crate dependency graph *if* they
need the compiler-rt intrinsics - this is a [breaking-change]. Users
of the `std` have to do nothing extra as the std crate depends
on compiler-builtins.
Finally, this a step towards lazy compilation of std with Cargo as the
compiler-rt intrinsics can now be built by Cargo instead of having to
be supplied by the user by some other method.
closes#34400
---
r? @alexcrichton
core: add likely and unlikely intrinsics
I'm no good at reading assembly, but I have tried a stage1 compiler with this patch, and it does cause different asm output. Additionally, testing this compiler on my httparse crate with some `likely` usage added in to the branches does affect benchmarks. However, I'm sure a codegen test should be included, if anyone knows what it should look like.
There isn't an entry in `librustc_trans/context.rs` in this diff, because it already exists (`llvm.expect.i1` is used for array indices).
----
Even though this does affect httparse benchmarks, it doesn't seem to affect it the same way GCC's `__builtin_expect` affects picohttpparser. I was confused that the deviation on the benchmarks grew hugely when testing this, especially since I'm absolutely certain that the branchs where I added `likely` were always `true`. I chalk that up to GCC and LLVM handle branch prediction differently.
cc #26179
Zero first byte of CString on drop
Hi! This is one more attempt to ameliorate `CString::new("...").unwrap().as_ptr()` problem (related RFC: https://github.com/rust-lang/rfcs/pull/1642).
One of the biggest problems with this code is that it may actually work in practice, so the idea of this PR is to proactively break such invalid code.
Looks like writing a `null` byte at the start of the CString should do the trick, and I think is an affordable cost: zeroing a single byte in `Drop` should be cheap enough compared to actual memory deallocation which would follow.
I would actually prefer to do something like
```Rust
impl Drop for CString {
fn drop(&mut self) {
let pattern = b"CTHULHU FHTAGN ";
let bytes = self.inner[..self.inner.len() - 1];
for (d, s) in bytes.iter_mut().zip(pattern.iter().cycle()) {
*d = *s;
}
}
}
```
because Cthulhu error should be much easier to google, but unfortunately this would be too expensive in release builds, and we can't implement things `cfg(debug_assertions)` conditionally in stdlib.
Not sure if the whole idea or my implementation (I've used ~~`transmute`~~ `mem::unitialized` to workaround move out of Drop thing) makes sense :)
Remove unnecessary `cmp::min` from BufWriter::write
The first branch of the if statement already checks if `buf.len() >= self.buf.capacity()`, which makes the `cmp::min(buf.len(), self.buf.capacity())` redundant: the result will always be `buf.len()`. Therefore, we can pass the `buf` slice directly into `Write::write`.
Update E0297 to new error format
Fixes#35521.
Part of #35233.
I didn't attempt the bonus of narrowing the span to focus on the "for `<pattern>`" piece (it's my first time contributing), but I'm happy to do so given some hints.
r? @jonathandturner
If a triple is configured only as a target, not a host, then trying to build
that triple with host artifacts would cause a panic. Fail a little nicer
instead.
Closes#36268
The recent Cargo update changed filenames, which broke a lot of incremental
rustbuild builds. What it thought were the output files were indeed no longer
the output files! (wreaking havoc).
This commit updates this to stop guessing filenames of Cargo and just manage
stamp files instead.
libcompiler-rt.a is dead, long live libcompiler-builtins.rlib
This commit moves the logic that used to build libcompiler-rt.a into a
compiler-builtins crate on top of the core crate and below the std crate.
This new crate still compiles the compiler-rt instrinsics using gcc-rs
but produces an .rlib instead of a static library.
Also, with this commit rustc no longer passes -lcompiler-rt to the
linker. This effectively makes the "no-compiler-rt" field of target
specifications a no-op. Users of `no_std` will have to explicitly add
the compiler-builtins crate to their crate dependency graph *if* they
need the compiler-rt intrinsics. Users of the `std` have to do nothing
extra as the std crate depends on compiler-builtins.
Finally, this a step towards lazy compilation of std with Cargo as the
compiler-rt intrinsics can now be built by Cargo instead of having to
be supplied by the user by some other method.
closes#34400
The span labels for associated types and consts were hardcoded to `Foo`
rather than substituting the name of the trait.
This also normalizes the wording for associated methods', traits', and
consts' span labels.
Fixes#36428.
fix a few errant `Krate` edges
Exploring the effect of small changes on `syntex` reuse, I discovered the following sources of unnecessary edges from `Krate`
r? @michaelwoerister
Improve char_lit's readability and speed
This is my first contribution to rustc. Please let me know if I've done anything wrong. (I ran `make tidy` before making the pull request.)
This reduces the time taken to run
`rustc -Zparse-only rustc-benchmarks/issue-32278-big-array-of-strings`
from 0.18s to 0.15s on my machine, and reduces the number of
instructions (as measured by Cachegrind) from 1.34B to 1.01B.
With the change applied, the time to fully compile that benchmark is
1.96s, so this is a 1.5% improvement.
Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element
Due to missing noalias annotations for &mut T in general (issue #31681),
in larger programs extend_from_slice and extend_with_element may both
compile very poorly. What is observed is that the .set_len() calls are
not lifted out of the loop, even for `Vec<u8>`.
Use a local length variable for the Vec length instead, and use a scope
guard to write this value back to self.len when the scope ends or on
panic. Then the alias analysis is easy.
This affects extend_from_slice, extend_with_element, the vec![x; n]
macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not
have triggered since inlining can be enough for the compiler to get it right).
Fixes#32155Fixes#33518Closes#17844
Point macros 1.1 errors to the input item
Moved from https://github.com/alexcrichton/rust/pull/6 to continue discussion. Fixes#36218.
Before:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:10:10
|
10 | #[derive(Serialize, Deserialize)]
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:15:15
|
15 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^ the trait `T` cannot be made into an object
```
After:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:11:1
|
11 | struct A {
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:16:1
|
16 | struct B<'a> {
| ^ the trait `T` cannot be made into an object
```
Add s390x support
This adds support for building the Rust compiler and standard
library for s390x-linux, allowing a full cross-bootstrap sequence
to complete. This includes:
- Makefile/configure changes to allow native s390x builds
- Full Rust compiler support for the s390x C ABI
(only the non-vector ABI is supported at this point)
- Port of the standard library to s390x
- Update the liblibc submodule to a version including s390x support
- Testsuite fixes to allow clean "make check" on s390x
Caveats:
- Resets base cpu to "z10" to bring support in sync with the default
behaviour of other compilers on the platforms. (Usually, upstream
supports all older processors; a distribution build may then chose
to require a more recent base version.) (Also, using zEC12 causes
failures in the valgrind tests since valgrind doesn't fully support
this CPU yet.)
- z13 vector ABI is not yet supported. To ensure compatible code
generation, the -vector feature is passed to LLVM. Note that this
means that even when compiling for z13, no vector instructions
will be used. In the future, support for the vector ABI should be
added (this will require common code support for different ABIs
that need different data_layout strings on the same platform).
- Two test cases are (temporarily) ignored on s390x to allow passing
the test suite. The underlying issues still need to be fixed:
* debuginfo/simd.rs fails because of incorrect debug information.
This seems to be a LLVM bug (also seen with C code).
* run-pass/union/union-basic.rs simply seems to be incorrect for
all big-endian platforms.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
The first branch of the if statement already checks if `buf.len() >= self.buf.capacity()`, which makes the `cmp::min(buf.len(), self.buf.capacity())` redundant: the result will always be `buf.len()`. Therefore, we can pass the `buf` slice directly into `Write::write`.
Update the wording for E0063. This will truncate the fields to 3.
Instead of listing every field it will now show missing `a`, `z`, `b`, and 1 other field
This is for #35218 as part of #35233
r? @jonathandturner
This adds support for building the Rust compiler and standard
library for s390x-linux, allowing a full cross-bootstrap sequence
to complete. This includes:
- Makefile/configure changes to allow native s390x builds
- Full Rust compiler support for the s390x C ABI
(only the non-vector ABI is supported at this point)
- Port of the standard library to s390x
- Update the liblibc submodule to a version including s390x support
- Testsuite fixes to allow clean "make check" on s390x
Caveats:
- Resets base cpu to "z10" to bring support in sync with the default
behaviour of other compilers on the platforms. (Usually, upstream
supports all older processors; a distribution build may then chose
to require a more recent base version.) (Also, using zEC12 causes
failures in the valgrind tests since valgrind doesn't fully support
this CPU yet.)
- z13 vector ABI is not yet supported. To ensure compatible code
generation, the -vector feature is passed to LLVM. Note that this
means that even when compiling for z13, no vector instructions
will be used. In the future, support for the vector ABI should be
added (this will require common code support for different ABIs
that need different data_layout strings on the same platform).
- Two test cases are (temporarily) ignored on s390x to allow passing
the test suite. The underlying issues still need to be fixed:
* debuginfo/simd.rs fails because of incorrect debug information.
This seems to be a LLVM bug (also seen with C code).
* run-pass/union/union-basic.rs simply seems to be incorrect for
all big-endian platforms.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Fix argument to FIONBIO ioctl
The FIONBIO ioctl takes as argument a pointer to an integer, which
should be either 0 or 1 to indicate whether nonblocking mode is to
be switched off or on. The type of the pointed-to variable is "int".
However, the set_nonblocking routine in libstd/sys/unix/net.rs passes
a pointer to a libc::c_ulong variable. This doesn't matter on all
32-bit platforms and on all litte-endian platforms, but it will
break on big-endian 64-bit platforms.
Found while porting Rust to s390x (a big-endian 64-bit platform).
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Follow target ABI sign-/zero-extension rules for enum types
While attempting to port Rust to s390x, I ran into an ABI violation
(that caused rust_eh_personality to be miscompiled, breaking unwinding).
The problem is that this function returns an enum type, which is
supposed to be sign-extended according to the s390x ABI. However,
common code would ignore target sign-/zero-extension rules for any
types that do not satisfy is_integral(), which includes enums.
For the general case of Rust enum types, which map to structure types
with a discriminant, that seems correct. However, in the special case
of simple enums that map directly to C enum types (i.e. LLVM integers),
this is incorrect; we must follow the target extension rules for those.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Changes the definition for opaque structs to look like `pub struct Vec<T>
{ /* fields omitted */ }` to save space on the page.
Also only use one line for empty braced structs.
Due to missing noalias annotations for &mut T in general (issue #31681),
in larger programs extend_from_slice and extend_with_element may both
compile very poorly. What is observed is that the .set_len() calls are
not lifted out of the loop, even for `Vec<u8>`.
Use a local length variable for the Vec length instead, and use a scope
guard to write this value back to self.len when the scope ends or on
panic. Then the alias analysis is easy.
This affects extend_from_slice, extend_with_element, the vec![x; n]
macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not
have triggered since inlining can be enough for the compiler to get it right).
Fix soundness bug described in #29859
This is an attempt at fixing the problems described in #29859 based on an IRC conversation between @nikomatsakis and I today. I'm waiting on a full build to come back, otherwise both tests trigger the correct error.
Removing the extraneous not_equal implementation for slices
Happened to stumble upon this one awhile back. Seemed a bit silly to have both the equals and not equals implementation when they're so similar.
macros: stackless expansion
After this PR, macro expansion cannot overflow the stack unless the expanded crate is too deep to fold.
Everything but the stackless placeholder expansion commit is also groundwork for macro modularization.
r? @nrc or @eddyb
rustbuild: per target musl-root
config.toml now accepts a target.$TARGET.musl-root key that lets you
override the "build" musl-root value, which is set via the --musl-root
flag or via the build.musl-root key.
With this change, it's now possible to compile std for several musl
targets at once. Here's are the sample commands to do such thing:
```
$ configure \
--enable-rustbuild \
--target=x86_64-unknown-linux-musl,arm-unknown-linux-musleabi \
--musl-root=/musl/x86_64-unknown-linux-musl/
$ edit config.toml && tail config.toml
[target.arm-unknown-linux-musleabi]
musl-root = "/x-tools/arm-unknown-linux-musleabi/arm-unknown-linux-musleabi/sysroot/usr"
$ make
```
r? @alexcrichton
With this we should be able to start producing releases of std for arm musl targets
rustdoc: Filter more incorrect methods inherited through Deref
Old code filtered out only static methods. This code also excludes &mut self methods if there is no DerefMut implementation.
Fixes#35169
The FIONBIO ioctl takes as argument a pointer to an integer, which
should be either 0 or 1 to indicate whether nonblocking mode is to
be switched off or on. The type of the pointed-to variable is "int".
However, the set_nonblocking routine in libstd/sys/unix/net.rs passes
a pointer to a libc::c_ulong variable. This doesn't matter on all
32-bit platforms and on all litte-endian platforms, but it will
break on big-endian 64-bit platforms.
Found while porting Rust to s390x (a big-endian 64-bit platform).
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
While attempting to port Rust to s390x, I ran into an ABI violation
(that caused rust_eh_personality to be miscompiled, breaking unwinding).
The problem is that this function returns an enum type, which is
supposed to be sign-extended according to the s390x ABI. However,
common code would ignore target sign-/zero-extension rules for any
types that do not satisfy is_integral(), which includes enums.
For the general case of Rust enum types, which map to structure types
with a discriminant, that seems correct. However, in the special case
of simple enums that map directly to C enum types (i.e. LLVM integers),
this is incorrect; we must follow the target extension rules for those.
Signed-off-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
resolve: Suggest `use self` when import resolves
Improves errors messages by replacing "Maybe a missing `extern crate`" messages
with "Did you mean `self::...`" when the `self` import would succeed.
Fixes#34191.
Thank you for the help @jseyfried!
Fix "field is never used" warning to take unions into account
When compiling code containing a union with an unused field, rustc says
"struct field is never used".
Rather than saying "struct or union", or adding logic to determine the
type of the item, just change the message to "field is never used",
dropping the "struct".
Update tests accordingly.
Before:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:10:10
|
10 | #[derive(Serialize, Deserialize)]
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:15:15
|
15 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^ the trait `T` cannot be made into an object
```
After:
```rust
error[E0106]: missing lifetime specifier
--> src/main.rs:11:1
|
11 | struct A {
| ^ expected lifetime parameter
error[E0038]: the trait `T` cannot be made into an object
--> src/main.rs:16:1
|
16 | struct B<'a> {
| ^ the trait `T` cannot be made into an object
```
incr. comp.: Take spans into account for ICH
This PR makes the ICH (incr. comp. hash) take spans into account when debuginfo is enabled.
A side-effect of this is that the SVH (which is based on the ICHs of all items in the crate) becomes sensitive to the tiniest change in a code base if debuginfo is enabled. Since we are not trying to model ABI compatibility via the SVH anymore (this is done via the crate disambiguator now), this should be not be a problem.
Fixes#33888.
Fixes#32753.
Updated E0559 to new format
Refactored a method that printed one suggested field name,
into a method that returns an `Option` of a suggestion
(Updated test cases accordingly)
r? @jonathandturner
Closes#36197
Update Error format for E0516, E0517, E0518
- E0518 Update error format #36111
- E0517 Update error format #36109
- E0516 Update error format #36108
- Part of #35233
r? @jonathandturner
Across crates only, converting a def-id into its def-key or def-path was
considered a read. This caused spurious reads when computing the symbol
name for some item.
The shadow graph supercedes the existing code that checked for
reads/writes without an active task and now adds the ability
to filter for specific edges.
It is useful to track down an errant edge that is being added. This is
not a perfect mechanism, since it doesn't consider (e.g.) if we are
in an ignored task, but it's helpful enough for now.
The goal here is to avoid writing to the `inherent_impls` map from
within the general `Coherence` task, and instead write to it as we
visit. Writing to it from the Coherence task is actually an information
leak; it happened to be safe because Coherence read from
`DepNode::Krate`, but that was very coarse.
I removed the `Rc` here because, upon manual inspection, nobody clones
the data in this table, and it meant that we can accumulate the data in
place. That said, the pattern that is used for the inherent impls map
is *generally* an anti-pattern (that is, holding the borrow lock for the
duration of using the contents), so it'd probably be better to
clone (and I doubt that would be expensive -- how many inherent impls
does a typical type have?).
config.toml now accepts a target.$TARGET.musl-root key that lets you
override the "build" musl-root value, which is set via the --musl-root
flag or via the build.musl-root key.
With this change, it's now possible to compile std for several musl
targets at once. Here's are the sample commands to do such thing:
```
$ configure \
--enable-rustbuild \
--target=x86_64-unknown-linux-musl,arm-unknown-linux-musleabi \
--musl-root=/musl/x86_64-unknown-linux-musl/
$ edit config.toml && tail config.toml
[target.arm-unknown-linux-musleabi]
musl-root = "/x-tools/arm-unknown-linux-musleabi/arm-unknown-linux-musleabi/sysroot/usr"
$ make
```
rustdoc: Fix associated consts in search results
Associated consts can appear in none trait impls so need to be treated
like methods when generating the search index.
Fixes#36031
Fix issue #36036.
Fix#36036.
We were treating an associated type as unsized even when the concrete instantiation was actually sized. Fix is to normalize before checking if it is sized.
Fix incorrect LLVM Linkage enum
Followup of #33994 to actually work.
The `Linkage` enum in librustc_llvm got out of sync with the version in LLVM and it caused two variants of the `#[linkage=""]` attribute to break.
This adds the functions `LLVMRustGetLinkage` and `LLVMRustSetLinkage` which convert between the Rust Linkage enum and the LLVM one, which should stop this from breaking every time LLVM changes it.
Possible remaining concerns:
1. There could be a codegen test to make sure that the attributes are applied correctly (I don't know how to do this).
2. ~~The test does not exercise the `appending` linkage. I can't figure out how to make a global static raw pointer to an array. This might not even be possible? If not we should probably remove appending linkage as its unusable in rust.~~ Appending linkage is not 'emittable' anyway.
3. The test only runs on Linux.
Fixes#33992
r? @alexcrichton
Typecheck refactor for `!`
Ping @nikomatsakis @eddyb. This is the PR for the typeck refactor for `!`. Is this what you guys had in mind? Is there anything else that needs doing on it?
We were treating an associated type as unsized even when the concrete
instantiation was actually sized. Fix is to normalize before checking
if it is sized.
Allow CompilerControllers to access rustc_plugin::registry::Registry
fixes#36064
I chose to put ructc_plugin::registry::Registry structure
into CompilerState structure, instead of Session structure.
This will preserve dependencies among librustc, libructc_driver, and libructc_plugin.
@jseyfried @sanxiyn
The `Linkage` enum in librustc_llvm got out of sync with the version in LLVM and it caused two variants of the #[linkage=""] attribute to break.
This adds the functions `LLVMRustGetLinkage` and `LLVMRustSetLinkage` which convert between the Rust Linkage enum and the LLVM one, which should stop this from breaking every time LLVM changes it.
Fixes#33992
Replace `_, _` with `..` in patterns
This is how https://github.com/rust-lang/rust/issues/33627 looks in action.
Looks especially nice in leftmost/rightmost positions `(first, ..)`/`(.., last)`.
I haven't touched libsyntax intentionally because the feature is still unstable.
rustbuild: add config.toml option to disable codegen tests
Fixes#36232.
I think it worked? Here's a build log where I tried to bootstrap, it crashed, then I added the setting to config.toml and it continued: https://gist.github.com/durka/cbf97cf04b8e065f1a2cfda4c1b6bf95
r? @alexcrichton
Update nightly docs supported Windows versions to match Getting Started page
https://doc.rust-lang.org/book/getting-started.html#tier-1 shows that Windows 7+ is officially supported (implying, for example Windows 10), but the nightly page only listed 7, 8, and Server 2008 R2).
Updated e0493 to new format (+ bonus).
Part of #35233.
Fixes#35999.
r? @jonathandturner
I'm not satisfied with the bonus part, there has to be an easier way to reach into the `Drop`'s span implementation. I'm all ears. :)
This option doesn't cause software FP routines
to be called it only changes the float ABI.
Additionally, this option is ignored by all targets,
except the ARM eabihf ones.
Add --Zsave-analysis-api
This is a save-analysis variation which can be used with libraries distributed without their source (e.g., libstd). It will allow IDEs and other tools to get info about types and create URLs to docs and source, without the unnecessary clutter of internal-only save-analysis info. I'm sure we'll iterate somewhat on the design, but this is a first draft.
Add --Zsave-analysis-api
This is a save-analysis variation which can be used with libraries distributed without their source (e.g., libstd). It will allow IDEs and other tools to get info about types and create URLs to docs and source, without the unnecessary clutter of internal-only save-analysis info. I'm sure we'll iterate somewhat on the design, but this is a first draft.
Fix optimization regressions for operations on [x; n]-initialized arrays.
Fixes#35662 by using `!=` instead of `<` as the stop condition for `[x; n]` initialization loops.
Also included is cc2009f02d, a hack to run the GVN pass twice, another time after InstCombine.
This hack results in removal of redundant `memset` and `memcpy` calls (from loops over arrays).
cc @nrc Can we get performance numbers on this? Not sure if it regresses anything else.
Rather than saying "struct or union" or adding logic to determine the
type of the item, just change the message to "field is never used",
dropping the "struct".
Update tests accordingly.
Implement untagged unions (RFC 1444)
cc https://github.com/rust-lang/rust/issues/32836
Notes:
- The RFC doesn't talk about `#[packed]` unions, this implementation supports them, packing changes union's alignment to 1 and removes trailing padding.
- The RFC doesn't talk about dynamically sized unions, this implementation doesn't support them and rejects them during wf-checking (similarly, dynamically sized enums are not supported as well).
- The lint for drop fields in unions can't work precisely before monomorphization, so it works pessimistically - non-`Copy` generic fields are reported, types not implementing `Drop` directly, but having non-trivial drop code are reported.
```
struct S(String); // Doesn't implement `Drop`
union U<T> {
a: S, // Reported
b: T, // Reported
}
```
- https://github.com/rust-lang/rust/pull/35764 was indeed helpful and landed timely, I didn't have to implement internal drop flags for unions.
- Unions are not permitted in constant patterns, because matching on union fields is unsafe, I didn't want unsafety checker to dig into all constants to uncover this possible unsafety.
- The RFC doesn't talk about `#[derive]`, generally trait impls cannot be derived for unions, but some of them can. I implemented only `#[derive(Copy)]` so far. In theory shallow `#[derive(Clone)]` can be derived as well if all union fields are `Copy`, I left it for later though, it requires changing how `Clone` impls are generated.
- Moving union fields is implemented as per https://github.com/rust-lang/rust/issues/32836#issuecomment-242511491.
- Testing strategy: union specific behavior is tested, sometimes very basically (e.g. debuginfo), behavior common for all ADTs (e.g. something like coherence
checks) is not generally tested.
r? @eddyb