Implementation of repr struct alignment RFC 1358.
The main changes around rustc::ty::Layout::struct:
* Added abi_align field which stores abi alignment before repr align is applied
* align field contains transitive repr alignment
* Added padding vec which stores padding required after fields
The main user of this information is rustc_trans::adt::struct_llfields
which determines the LLVM fields to be used by LLVM, including padding
fields.
A possible future optimisation would be to put the padding Vec in an Option, since it will be unused unless you are using repr align.
The main changes around rustc::ty::Layout::struct and rustc_trans:adt:
* Added primitive_align field which stores alignment before repr align
* Always emit field padding when generating the LLVM struct fields
* Added methods for adjusting field indexes from the layout index to the
LLVM struct field index
The main user of this information is rustc_trans::adt::struct_llfields
which determines the LLVM fields to be used by LLVM, including padding
fields.
Add a way to get shorter spans until `char` for pointing at defs
```rust
error[E0072]: recursive type `X` has infinite size
--> file.rs:10:1
|
10 | struct X {
| ^^^^^^^^ recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```
vs
```rust
error[E0072]: recursive type `X` has infinite size
--> file.rs:10:1
|
10 | struct X {
| _^ starting here...
11 | | x: X,
12 | | }
| |_^ ...ending here: recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```
Re: #35965, #38246. Follow up to #38328.
r? @jonathandturner
Move E0101 and E0102 logic into new E0282 mechanism #40013
Hello there!
## What's this?
Previously, me and @nikomatsakis worked on error messages of uninferred locals. (#38812)
This aims to build up on that by moving certain type checks from `writeback`.
With this, `E0101` and `E0102` errors are getting obsoleted and no longer thrown.
They're replaced with customized versions of `E0282`s instead.
## Sample Error Messages
#### `E0101` is getting converted into:
```rust
error[E0282]: type annotations needed
--> test.rs:2:14
|
2 | let x = |_| {};
| ^ consider giving this closure parameter a type
error: aborting due to previous error
```
#### `E0102` is getting converted into:
```rust
error[E0282]: type annotations needed
--> test.rs:2:9
|
2 | let x = [];
| ^
| |
| consider giving `x` a type
| cannot infer type for `[_; 0]`
error: aborting due to previous error
```
## Annoyances
- I think we need to change our way of type name resolving in relevant places, because that `[_; 0]` looks horrible IMHO.
- I'm not terribly happy with the note ordering of errors. So please do point to code that might help me accomplish this.
## Tests
Tests of `E0101` and `E0102` are getting converted from `compile-fail` to `ui` tests.
## Documentation
Please help me with documentation update. There are some confusing places that needed an update but I'm not sure if I did the right ones.
Please do comment on messages, layouts and other details.
## Appreciation
Huge thanks goes to @nikomatsakis for being a patient and humble mentor along this long journey. 🍻
I've added some explicit tests that negative impls are allowed to
overlap, and also to make sure that the feature doesn't interfere with
specialization. I've not added an explicit test for positive overlapping
with negative, as that's already tested elsewhere.
This patch allows overlap to occur between any two impls of a trait for
traits which have no associated items.
Several compile-fail tests around coherence had to be changed to add at
least one item to the trait they test against.
Ref #29864
Implement global_asm!() (RFC 1548)
This is a first attempt. ~~One (potential) problem I haven't solved is how to handle multiple usages of `global_asm!` in a module/crate. It looks like `LLVMSetModuleInlineAsm` overwrites module asm, and `LLVMAppendModuleInlineAsm` is not provided in LLVM C headers 😦~~
I can provide more detail as needed, but honestly, there's not a lot going on here.
r? @eddyb
CC @Amanieu @jackpot51
Tracking issue: #35119
Handle subtyping in inference through obligations
We currently store subtyping relations in the `TypeVariables` structure as a kind of special case. This branch uses normal obligations to propagate subtyping, thus converting our inference variables into normal fallback. It also does a few other things:
- Removes the (unstable, outdated) support for custom type inference fallback.
- It's not clear how we want this to work, but we know that we don't want it to work the way it currently does.
- The existing support was also just getting in my way.
- Fixes#30225, which was caused by the trait caching code pretending type variables were normal unification variables, when indeed they were not (but now are).
There is one fishy part of these changes: when computing the LUB/GLB of a "bivariant" type parameter, I currently return the `a` value. Bivariant type parameters are only allowed in a very particular situation, where the type parameter is only used as an associated type output, like this:
```rust
pub struct Foo<A, B>
where A: Fn() -> B
{
data: A
}
```
In principle, if one had `T=Foo<A, &'a u32>` and `U=Foo<A, &'b u32>` and (e.g.) `A: for<'a> Fn() -> &'a u32`, then I think that computing the LUB of `T` and `U` might do the wrong thing. Probably the right behavior is just to create a fresh type variable. However, that particular example would not compile (because the where-clause is illegal; `'a` does not appear in any input type). I was not able to make an example that *would* compile and demonstrate this shortcoming, and handling the LUB/GLB was mildly inconvenient, so I left it as is. I am considering whether to revisit this or what.
I have started a crater run to test the impact of these changes.
```rust
error[E0072]: recursive type `X` has infinite size
--> file.rs:10:1
|
10 | struct X {
| ^^^^^^^^ recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```
vs
```rust
error[E0072]: recursive type `X` has infinite size
--> file.rs:10:1
|
10 | struct X {
| _^ starting here...
11 | | x: X,
12 | | }
| |_^ ...ending here: recursive type has infinite size
|
= help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `X` representable
```
In some cases, we give multiple primary spans, in which case we would
report one `//~` annotation per primary span. That was very confusing
because these things are reported to the user as a single error.
UI tests would be better here.
Explicit help message for binop type mismatch
When trying to do `1 + Some(2)`, or some other binary operation on two
types different types without an appropriate trait implementation, provide
an explicit help message:
```rust
help: `{integer} + std::option::Option<{integer}>` has no implementation
```
Re: #39579, #38564, #37626, #39942, #34698.
When trying to do a binary operation with missing implementation, for
example `1 + Some(2)`, provide an explicit help message:
```
note: no implementation for `{integer} + std::option::Option<{integer}>`
```
Use `rustc_on_unimplemented` for the suggestions. Move cfail test to ui.
-Z linker-flavor
(Please read the commit message first)
This PR is an alternative to rust-lang/rust#36120 (internal lld linker). The
main goal of this PR is to make it *possible* to use LLD as a linker to allow
out of tree experimentation. Now that LLD is going to be shipped with LLVM 4.0,
it should become easier to get a hold of LLD (hopefully, it will be packaged by
Linux distros soon).
Since LLD is a multiarch linker, it has the potential to make cross compilation
easier (less tools need to be installed). Supposedly, LLD is also faster than
the gold linker so LLD may improve build times where link times are significant
(e.g. 100% incremental compilation reuse).
The place where LLD shines is at linking Rust programs that don't depend on
system libraries. For example, here's how you would link a bare metal ARM
Cortex-M program:
```
$ xargo rustc --target thumbv7m-none-eabi -- -Z linker-flavor=ld -C linker=ld.lld -Z print-link-args
"ld.lld" \
"-L" \
"$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib" \
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-de1f86df314ad68c.0.o" \
"-o" \
"$PWD/target/thumbv7m-none-eabi/debug/deps/app-de1f86df314ad68c" \
"--gc-sections" \
"-L" \
"$PWD/target/thumbv7m-none-eabi/debug/deps" \
"-L" \
"$PWD/target/debug/deps" \
"-L" \
"$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib" \
"-Bstatic" \
"-Bdynamic" \
"$XARGO_HOME/lib/rustlib/thumbv7m-none-eabi/lib/libcore-11670d2bd4951fa7.rlib"
$ file target/thumbv7m-none-eabi/debug/app
app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped, with debug_info
```
This doesn't require installing the `arm-none-eabi-gcc` toolchain.
Even cooler (but I'm biased) is that you can link Rust programs that use
[`steed`] (`steed` is a `std` re-implementation free of C dependencies for Linux
systems) instead of `std` for a bunch of different architectures without having
to install a single cross toolchain.
[`steed`]: https://github.com/japaric/steed
```
$ xargo rustc --target aarch64-unknown-linux-steed --example hello --release -- -Z print-link-args
"ld.lld" \
"-L" \
"$XARGO_HOME/lib/rustlib/aarch64-unknown-linux-steed/lib" \
"$PWD/target/aarch64-unknown-linux-steed/release/examples/hello-80c130ad884c0f8f.0.o" \
"-o" \
"$PWD/target/aarch64-unknown-linux-steed/release/examples/hello-80c130ad884c0f8f" \
"--gc-sections" \
"-L" \
"$PWD/target/aarch64-unknown-linux-steed/release/deps" \
"-L" \
"$PWD/target/release/deps" \
"-L" \
"$XARGO_HOME/lib/rustlib/aarch64-unknown-linux-steed/lib" \
"-Bstatic" \
"-Bdynamic" \
"/tmp/rustc.lAybk9Ltx93Q/libcompiler_builtins-589aede02de78434.rlib"
$ file target/aarch64-unknown-linux-steed/release/examples/hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, not stripped, with debug_info
```
All these targets (architectures) worked with LLD:
- [aarch64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/aarch64-unknown-linux-steed.json)
- [arm-unknown-linux-steedeabi](https://github.com/japaric/steed/blob/lld/docker/arm-unknown-linux-steedeabi.json)
- [arm-unknown-linux-steedeabihf](https://github.com/japaric/steed/blob/lld/docker/arm-unknown-linux-steedeabihf.json)
- [armv7-unknown-linux-steedeabihf](https://github.com/japaric/steed/blob/lld/docker/armv7-unknown-linux-steedeabihf.json)
- [i686-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/i686-unknown-linux-steed.json)
- [mips-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/mips-unknown-linux-steed.json)
- [mipsel-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/mipsel-unknown-linux-steed.json)
- [powerpc-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/powerpc-unknown-linux-steed.json)
- [powerpc64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/powerpc64-unknown-linux-steed.json)
- [x86_64-unknown-linux-steed](https://github.com/japaric/steed/blob/lld/docker/x86_64-unknown-linux-steed.json)
---
The case where lld is unergonomic is linking binaries that depend on system
libraries. Like "Hello, world" for `x86_64-unknown-linux-gnu`. Because you have
to pass as linker arguments: the path to the startup objects, the path to the
dynamic linker and the library search paths. And all those are system specific
so they can't be encoded in the target itself.
```
$ cargo \
rustc \
--release \
-- \
-C \
linker=ld.lld \
-Z \
linker-flavor=ld \
-C \
link-args='-dynamic-linker /lib64/ld-linux-x86-64.so.2 -L/usr/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1 /usr/lib/Scrt1.o /usr/lib/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/crtbeginS.o /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.1/crtendS.o /usr/lib/crtn.o'
```
---
Another case where `-Z linker-flavor` may come in handy is directly calling
Solaris' linker which is also a multiarch linker (or so I have heard). cc
@binarycrusader
cc @alexcrichton
Heads up: [breaking-change] due to changes in the target specification format.
Fixed ICEs with pattern matching in const expression
Fixed 2 ICEs with when pattern matching inside a constant expression.
Both of these ICEs now resolve to an appropriate compiler error.
1. ICE was caused by a compiler bug to implement discriminant const qualify.
I removed this intentionally thrown bug and changed it to a FIXME as the unimplemented expression type is handled as a compiler error elsewhere.
2. ICE was caused during a drop check when checking if a variable lifetime outlives the current scope if there was no parent scope .
I've changed it to stop checking if there is no parent scope for the current scope. It is valid syntax for a const variable to be assigned a match expression with no enclosing scope.
The ICE seemed to mainly be used as a defensive check for bugs elsewhere.
Fixes#38199.
Fixes#31577.
Fixes#29093.
Fixes#40012.
Suggest using enum when a variant is used as a type
Given a file:
```rust
enum Fruit {
Apple(i64),
Orange(i64),
}
fn should_return_fruit() -> Apple {
Apple(5)
}
```
Provide the following output:
```rust
error[E0412]: cannot find type `Apple` in this scope
--> file.rs:16:29
|
16 | fn should_return_fruit() -> Apple {
| ^^^^^ not found in this scope
|
help: there is an enum variant `Fruit::Apple`, did you mean to use `Fruit`?
--> file.rs:12:5
|
12 | Apple(i64),
| ^^^^^^^^^^
error[E0425]: cannot find function `Apple` in this scope
--> file.rs:17:5
|
17 | Apple(5)
| ^^^^^ not found in this scope
|
= help: possible candidate is found in another module, you can import it into scope:
`use Fruit::Apple;`
```
Fix#35675.
#[used] attribute
(For an explanation of what this feature does, read the commit message)
I'd like to propose landing this as an experimental feature (experimental as in:
no clear stabilization path -- like `asm!`, `#[linkage]`) as it's low
maintenance (I think) and relevant to the "Usage in resource-constrained
environments" exploration area.
The main use case I see is running code before `main`. This could be used, for
instance, to cheaply initialize an allocator before `main` where the alternative
is to use `lazy_static` to initialize the allocator on its first use which it's
more expensive (atomics) and doesn't work on ARM Cortex-M0 microcontrollers (no
`AtomicUsize` on that platform)
Here's a `std` example of that:
``` rust
unsafe extern "C" fn before_main_1() {
println!("Hello");
}
unsafe extern "C" fn before_main_2() {
println!("World");
}
#[link_section = ".init_arary"]
#[used]
static INIT_ARRAY: [unsafe extern "C" fn(); 2] = [before_main_1, before_main_2];
fn main() {
println!("Goodbye");
}
```
```
$ rustc -C lto -C opt-level=3 before_main.rs
$ ./before_main
Hello
World
Goodbye
```
In general, this pattern could be used to let *dependencies* run code before
`main` (which sounds like it could go very wrong in some cases). There are
probably other use cases; I hope that the people I have cc-ed can comment on
those.
Note that I'm personally unsure if the above pattern is something we want to
promote / allow and that's why I'm proposing this feature as experimental. If
this leads to more footguns than benefits then we can just axe the feature.
cc @nikomatsakis ^ I know you have some thoughts on having a process for
experimental features though I'm fine with writing an RFC before landing this.
- `dead_code` lint will have to be updated to special case `#[used]` symbols.
- Should we extend `#[used]` to work on non-generic functions?
cc rust-lang/rfcs#1002
cc rust-lang/rfcs#1459
cc @dpc @JinShil
Make 'overlapping_inherent_impls' lint a hard error
This is ought to be implemented in PR #40728. Unfortunately, when I rebased the PR to resolve merge conflict, the "hard error" code disappeared. This PR complements the initial PR.
Now the following rust code gives the following error:
```rust
struct Foo;
impl Foo {
fn id() {}
}
impl Foo {
fn id() {}
}
fn main() {}
```
```
error[E0592]: duplicate definitions with name `id`
--> /home/topecongiro/test.rs:4:5
|
4 | fn id() {}
| ^^^^^^^^^^ duplicate definitions for `id`
...
8 | fn id() {}
| ---------- other definition for `id`
error: aborting due to previous error
```
rustc: Stabilize the `#![windows_subsystem]` attribute
This commit stabilizes the `#![windows_subsystem]` attribute which is a
conservative exposure of the `/SUBSYSTEM` linker flag on Widnows platforms. This
is useful for creating applications as well as console programs.
Closes#37499