On type mismatch involving associated type, suggest constraint
When an associated type is found when a specific type was expected, if
possible provide a structured suggestion constraining the associated
type in a bound.
```
error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
--> $DIR/associated-types-multiple-types-one-trait.rs:13:5
|
LL | want_y(t);
| ^^^^^^ expected `i32`, found associated type
...
LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
| ----- required by this bound in `want_y`
|
= note: expected type `i32`
found associated type `<T as Foo>::Y`
help: consider constraining the associated type `<T as Foo>::Y` to `i32`
|
LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T)
| ^^^^^^^^^
```
```
error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:12:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
|
= note: expected type `usize`
found associated type `<impl Trait as Trait>::A`
help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize`
|
LL | fn foo(x: impl Trait<A = usize>) {
| ^^^^^^^^^^
```
Fix#71035. Related to #70908.
When an associated type is found when a specific type was expected, if
possible provide a structured suggestion constraining the associated
type in a bound.
```
error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
--> $DIR/associated-types-multiple-types-one-trait.rs:13:5
|
LL | want_y(t);
| ^^^^^^ expected `i32`, found associated type
...
LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
| ----- required by this bound in `want_y`
|
= note: expected type `i32`
found associated type `<T as Foo>::Y`
help: consider constraining the associated type `<T as Foo>::Y` to `i32`
|
LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T)
| ^^^^^^^^^
```
```
error[E0308]: mismatched types
--> $DIR/trait-with-missing-associated-type-restriction.rs:12:9
|
LL | qux(x.func())
| ^^^^^^^^ expected `usize`, found associated type
|
= note: expected type `usize`
found associated type `<impl Trait as Trait>::A`
help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize`
|
LL | fn foo(x: impl Trait<A = usize>) {
| ^^^^^^^^^^
```
Suggest deref when coercing `ty::Ref` to `ty::RawPtr`
Fixes#32122
Currently we do autoderef when casting `ty::Ref` ->`ty::Ref`, but we don't autoderef when casting `ty::Ref` -> `ty::RawPtr`. This PR make the compiler suggests deref when coercing `ty::Ref` to `ty::RawPtr`
rustc: fix check_attr() for methods, closures and foreign functions
This fixes an issue that previously turned up for methods in https://github.com/rust-lang/rust/pull/69274, but also exists for closures and foreign function: `check_attr` does not call `codegen_fn_attrs()` for these types when it should, meaning that incorrectly used function attributes are not diagnosed without codegen.
The issue affects our UI tests, as they run with `--emit=metadata` by default, but as it turns out, this is not the only case: Function attributes are not checked on any dead code without this fix!
This makes the fix a **breaking change**. The following very silly Rust programs compiles fine on stable Rust when it should not, which is fixed by this PR.
```rust
fn main() {
#[target_feature(enable = "sse2")]
|| {};
}
```
I assume any real-world program which may trigger this issue would at least emit a dead code warning, but of course that is no guarantee that such code does not exist...
Fixes#70307
Add all remaining `DefKind`s.
r? @eddyb or @Centril
~~I'm not sure if this is what you were thinking of. There are also a few places where I'm not sure what the correct choice is because I don't fully understand the meaning of some variants.~~
~~In general, it feels a bit odd to add some of these as `DefKind`s (e.g. `Arm`) because they don't feel like definitions. Are there things that it makes sense not to add?~~
Only run dataflow for const qualification if type-based check would fail
This is the optimization discussed in https://github.com/rust-lang/rust/issues/49146#issuecomment-614012476. We wait for `Qualif::in_any_value_of_ty` to return `true` before running dataflow. For bodies that deal mostly with primitive types, this will avoid running dataflow at all during const qualification.
This also removes the `BitSet` used to cache `in_any_value_of_ty` for each local, which was only necessary for an old version of #64470 that also handled promotability.
Lint must_use on mem::replace
This adds a hint on `mem::replace`, "if you don't need the old value,
you can just assign the new value directly". This is in similar spirit
to the `must_use` on `ManuallyDrop::take`.
Detect mistyped associated consts in `Instance::resolve`.
*Based on #71049 to prevent redundant/misleading downstream errors.*
Fixes#70942 by refusing to resolve an associated `const` if it doesn't have the same type in the `impl` that it does in the `trait` (which we assume had errored, and `delay_span_bug` guards against bugs).
When the return type is `!Sized` we look for all the returned
expressions in the body to fetch their types and provide a reasonable
suggestion. The tail expression of the body is normally evaluated after
checking whether the return type is `Sized`. Changing the order of the
evaluation produces undesirable knock down effects, so we detect the
specific case that newcomers are likely to encounter ,returning a single
bare trait object, and only in that case we evaluate the tail
expression's type so that the suggestion will be accurate.
During development, a function could have a return type set that is a
bare trait object by accident. We already suggest using either a boxed
trait object or `impl Trait` if the return paths will allow it. We now
do so too when there are *no* return paths or they all resolve to `!`.
We still don't handle cases where the trait object is *not* the entirety
of the return type gracefully.
When evaluating the derived obligations from super traits, maintain a
reference to the original obligation in order to give more actionable
context in the output.
ci: run mir-opt tests on PR CI also as 32-bit (for `EMIT_MIR_FOR_EACH_BIT_WIDTH`).
Background: #69916 and [`src/test/mir-opt/README.md`](https://github.com/rust-lang/rust/blob/master/src/test/mir-opt/README.md):
> By default 32 bit and 64 bit targets use the same dump files, which can be problematic in the
presence of pointers in constants or other bit width dependent things. In that case you can add
>
> ```
> // EMIT_MIR_FOR_EACH_BIT_WIDTH
> ```
>
> to your test, causing separate files to be generated for 32bit and 64bit systems.
However, if you change the output of such a test (intentionally or not), or if you add a test and it varies between 32-bit and 64-bit platforms, you have to run this command (for a x64 linux host):
`./x.py test --stage 1 --target x86_64-unknown-linux-gnu --target i686-unknown-linux-gnu --bless src/test/mir-opt`
Otherwise, bors trying to merge the PR will fail, since we test 32-bit targets there.
But we don't on PR CI, which means there's no way the PR author would know (unless they were burnt by this already and know what to look for).
This PR resolves that by running `mir-opt` tests for ~~`i686-unknown-linux-gnu`~~, on PR CI.
**EDIT**: switched to `armv5te-unknown-linux-gnueabi` to work around LLVM 7 crashes (see https://github.com/rust-lang/compiler-builtins/pull/311#issuecomment-612270089), found during testing.
cc @rust-lang/wg-mir-opt @rust-lang/infra
rustc: Add a warning count upon completion
This adds a `build completed with one warning/x warnings` message, similar to the already present `aborted due to previous error` message.