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.
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
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
The `try_coerce` method coerces from a source to a target
type, possibly inserting adjustments. It should guarantee
that the post-adjustment type is a subtype of the target type
(or else that some side-constraint has been registered which will lead
to an error). However, it used to return the (possibly adjusted) source
as the type of the expression rather than the target. This led to
less good downstream errors.
To work around this, the code around blocks -- and particular tail
expressions in blocks -- had some special case manipulation. However,
since that code is now using the more general `CoerceMany` construct (to
account for breaks), it can no longer take advantage of that. This lead
to some regressions in compile-fail tests were errors were reported at
"less good" locations than before.
This change modifies coercions to return the target type when successful
rather the source type. This extends the behavior from blocks to all
coercions. Typically this has limited effect but on a few tests yielded
better errors results (and avoided regressions, of course).
This change also restores the hint about removing semicolons which went
missing (by giving 'force-unit' coercions a chance to add notes etc).
First, we keep a `CoerceMany` now to find the LUB of all the break
expressions. Second, this `CoerceMany` is actually an
`Option<CoerceMany>`, and we store `None` for loops where "break with an
expression" is disallowed. This avoids silly duplicate errors about a
type mismatch, since the loops pass already reports an error that the
break cannot have an expression. Finally, since we now detect an invalid
break target during HIR lowering, refactor `find_loop` to be infallible.
Adjust tests as needed:
- some spans from breaks are slightly different
- break up a single loop into multiple since `CoerceMany` silences
redundant and derived errors
- add a ui test that we only give on error for loop-break-value