Use a more targeted span when suggesting casting an `fn` item to an `fn` pointer.
```
error[E0308]: cannot coerce functions which must be inlined to function pointers
--> $DIR/cast.rs:10:33
|
LL | let _: fn(isize) -> usize = callee;
| ------------------ ^^^^^^ cannot coerce functions which must be inlined to function pointers
| |
| expected due to this
|
= note: expected fn pointer `fn(_) -> _`
found fn item `fn(_) -> _ {callee}`
= note: fn items are distinct from fn pointers
help: consider casting to a fn pointer
|
LL | let _: fn(isize) -> usize = callee as fn(isize) -> usize;
| +++++++++++++++++++++
```
```
error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch.rs:42:30
|
LL | let d: &fn(u32) -> u32 = foo;
| --------------- ^^^ expected `&fn(u32) -> u32`, found fn item
| |
| expected due to this
|
= note: expected reference `&fn(_) -> _`
found fn item `fn(_) -> _ {foo}`
help: consider using a reference
|
LL | let d: &fn(u32) -> u32 = &foo;
| +
```
Previously we'd point at the whole expression for replacement, instead of marking what was being added.
We could also modify the suggestions for `&(name as fn())`, but for that we require storing more accurate spans than we have now.
Account for mutable borrow in argument suggestion
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
instead of
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
Fix#136028.
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
instead of
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|
```
Fix#136028.
```
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:5
|
LL | object = &object2;
| ^^^^^^
|
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:1:9
|
LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^^^
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object2(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument, trying to avoid an E0308.
```
error[E0308]: mismatched types
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:6:14
|
LL | fn change_object(mut object: &Object) {
| ------- expected due to this parameter type
LL | let object2 = Object;
LL | object = object2;
| ^^^^^^^ expected `&Object`, found `Object`
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
|
```
This might be the first thing someone tries to write to mutate the value *behind* an argument. We avoid suggesting `object = &object2;`, as that is less likely to be what was intended.
The SCCs of the region graph are not a reliable heuristic to use for blaming an interesting
constraint for diagnostics. For region errors, if the outlived region is `'static`, or the involved
types are invariant in their lifetiems, there will be cycles in the constraint graph containing both
the target region and the most interesting constraints to blame. To get better diagnostics in these
cases, this commit removes that heuristic.
Cleanup: delete `//@ pretty-expanded` directive
This PR removes the `//@ pretty-expanded` directive support in compiletest and removes its usage inside ui tests because it does not actually do anything, and its existence is itself misleading. This PR is split into two commits:
1. The first commit just drops `pretty-expanded` directive support in compiletest.
2. The second commit is created by `sd '//@ pretty-expanded.*\n' '' tests/ui/**/*.rs`[^1], reblessing, and slightly adjusting some leading whitespace in a few tests.
We can tell this is fully removed because compiletest doesn't complain about unknown directive when running the `ui` test suite.
cc #23616
### History
Originally, there was some effort to introduce more test coverage for `-Z unpretty=expanded` (in 2015 this was called `--pretty=expanded`). In [Make it an error to not declare used features #23598][pr-23598], there was a flip from `//@ no-pretty-expanded` (opt-out of `-Z
unpretty=expanded` test) to `//@ pretty-expanded` (opt-in to `-Z unpretty=expanded` test). This was needed because back then the dedicated `tests/pretty` ("pretty") test suite did not existed, and the pretty tests were grouped together under `run-pass` tests (I believe the `ui` test suite didn't exist back then either). Unfortunately, in this process the replacement `//@ pretty-expanded` directives contained a `FIXME #23616` linking to [There are very few tests for `-Z unpretty` expansion #23616][issue-23616]. But this was arguably backwards and somewhat misleading, as noted in [#23616](https://github.com/rust-lang/rust/issues/23616#issuecomment-484999901):
The attribute is off by default and things just work if you don't
test it, people have not been adding the `pretty-expanded`
annotation to new tests even if it would work.
Which basically renders this useless.
### Current status
As of Nov 2024, we have a dedicated `pretty` test suite, and some time over the years the split between `run-pass` into `ui` and `pretty` test suites caused all the `//@ pretty-expanded` in `ui` tests to do absolutely nothing: the compiletest logic for `pretty-expanded` only triggers in the *pretty* test suite, but none of the pretty tests use it. Oops.
Nobody remembers this, nobody uses this, it's misleading in ui tests. Let's get rid of this directive altogether.
[pr-23598]: https://github.com/rust-lang/rust/pull/23598
[issue-23616]: https://github.com/rust-lang/rust/issues/23616
### Follow-ups
- [x] Yeet this directive from rustc-dev-guide docs. https://github.com/rust-lang/rustc-dev-guide/pull/2147
[^1]: https://github.com/chmln/sd
r? compiler
Use ordinal number in argument error
Add an ordinal number to two argument errors ("unexpected" and "missing") for ease of understanding error.
```
error[E0061]: this function takes 3 arguments but 2 arguments were supplied
--> test.rs:11:5
|
11 | f(42, 'a');
| ^ --- 2nd argument of type `f32` is missing
|
(snip)
error[E0061]: this function takes 3 arguments but 4 arguments were supplied
--> test.rs:12:5
|
12 | f(42, 42, 1.0, 'a');
| ^ ----
| | |
| | unexpected 2nd argument of type `{integer}`
| help: remove the extra argument
```
To get an ordinal number, I copied `ordinalize` from other crate `rustc_resolve` because I think it is too much to link `rustc_resolve` for this small function. Please let me know if there is a better way.
Go over all structured parser suggestions and make them verbose style.
When suggesting to add or remove delimiters, turn them into multiple suggestion parts.
Use parenthetical notation for `Fn` traits
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Address #67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Always use the `Fn(T) -> R` format when printing closure traits instead of `Fn<(T,), Output = R>`.
Fix#67100:
```
error[E0277]: expected a `Fn()` closure, found `F`
--> file.rs:6:13
|
6 | call_fn(f)
| ------- ^ expected an `Fn()` closure, found `F`
| |
| required by a bound introduced by this call
|
= note: wrap the `F` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `call_fn`
--> file.rs:1:15
|
1 | fn call_fn<F: Fn() -> ()>(f: &F) {
| ^^^^^^^^^^ required by this bound in `call_fn`
help: consider further restricting this bound
|
5 | fn call_any<F: std::any::Any + Fn()>(f: &F) {
| ++++++
```
Allow coercing functions whose signature differs in opaque types in their defining scope into a shared function pointer type
r? `@compiler-errors`
This accepts more code on stable. It is now possible to have match arms return a function item `foo` and a different function item `bar` in another, and that will constrain OpaqueTypeInDefiningScope to have the hidden type ConcreteType and make the type of the match arms a function pointer that matches the signature. So the following function will now compile, but on master it errors with a type mismatch on the second match arm
```rust
fn foo<T>(t: T) -> T {
t
}
fn bar<T>(t: T) -> T {
t
}
fn k() -> impl Sized {
fn bind<T, F: FnOnce(T) -> T>(_: T, f: F) -> F {
f
}
let x = match true {
true => {
let f = foo;
bind(k(), f)
}
false => bar::<()>,
};
todo!()
}
```
cc https://github.com/rust-lang/rust/issues/116652
This is very similar to https://github.com/rust-lang/rust/pull/123794, and with the same rationale:
> this is for consistency with `-Znext-solver`. the new solver does not have the concept of "non-defining use of opaque" right now and we would like to ideally keep it that way. Moving to `DefineOpaqueTypes::Yes` in more cases removes subtlety from the type system. Right now we have to be careful when relating `Opaque` with another type as the behavior changes depending on whether we later use the `Opaque` or its hidden type directly (even though they are equal), if that later use is with `DefineOpaqueTypes::No`*
Start pointing to where bindings were declared when they are captured in closures:
```
error[E0597]: `x` does not live long enough
--> $DIR/suggest-return-closure.rs:23:9
|
LL | let x = String::new();
| - binding `x` declared here
...
LL | |c| {
| --- value captured here
LL | x.push(c);
| ^ borrowed value does not live long enough
...
LL | }
| -- borrow later used here
| |
| `x` dropped here while still borrowed
```
Suggest cloning in more cases involving closures:
```
error[E0507]: cannot move out of `foo` in pattern guard
--> $DIR/issue-27282-move-ref-mut-into-guard.rs:11:19
|
LL | if { (|| { let mut bar = foo; bar.take() })(); false } => {},
| ^^ --- move occurs because `foo` has type `&mut Option<&i32>`, which does not implement the `Copy` trait
| |
| `foo` is moved here
|
= note: variables bound in patterns cannot be moved from until after the end of the pattern guard
help: consider cloning the value if the performance cost is acceptable
|
LL | if { (|| { let mut bar = foo.clone(); bar.take() })(); false } => {},
| ++++++++
```
- Firstly get all the information about generics matching out of the HIR
- Secondly the labelling for the function is more coherent now
- Lastly a few error message improvements
This function is now used to check `#[panic_handler]`, `start` lang item, `main`, `#[start]` and intrinsic functions.
The diagnosis produced are now closer to the ones produced by trait/impl method signature mismatch.