Tweak irrefutable let else warning output
Fixes https://github.com/rust-lang/rust/issues/153454
Greeting!
This PR tweak diagnostic output for `irrefutable-let-else` patterns and adds a check for `let a = Some(b) else {...}`
Thanks for the review!
```
help: consider using `let Some(name) = case` to match on a specific variant
|
LL - let name = Some(case) else {
LL + let Some(name) = case else {
|
```
Fix ICE in borrowck mutability suggestion with multi-byte ref sigil
Fixesrust-lang/rust#139089
Similarly to rust-lang/rust#155068, this is another instance where span arithmetic did not account for multi-byte characters. (Note that the ampersand in the test is full-width)
This change also results in correcting some inappropriate suggestions.
`span_suggestions` is to provide mutually exclusive suggestions. When it was introduced, we made its behavior be that if a single suggestion is given to it, we present the suggestion inline, otherwise in patch format. Changing this to make all of its uses be verbose, as that is closer in intent of output.
Fix ICE in `span_extend_prev_while` with multibyte characters
Fixes https://github.com/rust-lang/rust/issues/155037
The function assumed that the character found by `rfind` was always one byte wide, using a hardcoded `1` instead of `c.len_utf8()`. When a multibyte character appeared immediately before the span, this caused the resulting span to point into the middle of a UTF-8 sequence, triggering an assertion failure in `bytepos_to_file_charpos`.
Remove "failed to resolve" and use the same format we use in other resolution errors "cannot find `name`".
```
error[E0433]: cannot find `nonexistent` in `existent`
--> $DIR/custom_attr_multisegment_error.rs:5:13
|
LL | #[existent::nonexistent]
| ^^^^^^^^^^^ could not find `nonexistent` in `existent`
```
```
error[E0308]: mismatched types
--> $DIR/macro-span-caller-replacement.rs:5:17
|
LL | s = format!("{arg}");
| ^^^^^^^^^^^^^^^^ expected `&str`, found `String`
...
LL | macro_with_format!();
| -------------------- in this macro invocation
|
= note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info)
```
Improve diagnostics for buffer reuse with borrowed references
Addresses rust-lang/rust#147694
I'm not sure the current note wording is the best so I appreciate any feedback.
Point at statics and consts being mutable borrowed or written to:
```
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:4:5
|
LL | static NUM: i32 = 18;
| --------------- this `static` cannot be written to
...
LL | NUM = 20;
| ^^^^^^^^ cannot assign
```
Point at the expression that couldn't be mutably borrowed from a pattern:
```
error[E0596]: cannot borrow data in a `&` reference as mutable
--> $DIR/mut-pattern-of-immutable-borrow.rs:19:14
|
LL | match &arg.field {
| ---------- this cannot be borrowed as mutable
LL | Some(ref mut s) => s.push('a'),
| ^^^^^^^^^ cannot borrow as mutable
```
```
error[E0277]: the trait bound `[[u16; 3]; 2]: Bar` is not satisfied
--> $DIR/issue-67185-2.rs:21:6
|
LL | impl Foo for FooImpl {}
| ^^^ the trait `Bar` is not implemented for `[[u16; 3]; 2]`
|
help: the following other types implement trait `Bar`
--> $DIR/issue-67185-2.rs:9:1
|
LL | impl Bar for [u16; 4] {}
| ^^^^^^^^^^^^^^^^^^^^^ `[u16; 4]`
LL | impl Bar for [[u16; 3]; 3] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `[[u16; 3]; 3]`
note: required by a bound in `Foo`
--> $DIR/issue-67185-2.rs:14:30
|
LL | trait Foo
| --- required by a bound in this trait
LL | where
LL | [<u8 as Baz>::Quaks; 2]: Bar,
| ^^^ required by this bound in `Foo`
```
We'll still error due to the `opt_bad_ty` of `method_autoderef_steps`.
This slightly worsens the span of `infer_var.method()` which is now the
same as for `Box::new(infer_var).method()`.
Unlike `structurally_resolve_type`, `probe_op` does not check whether
the infcx is already tainted, so this results in 2 previously not emitted
errors.
```
error[E0408]: variable `Ban` is not bound in all patterns
--> f12.rs:9:9
|
9 | (Foo,Bar)|(Ban,Foo) => {}
| ^^^^^^^^^ --- variable not in all patterns
| |
| pattern doesn't bind `Ban`
|
help: you might have meant to use the similarly named previously used binding `Bar`
|
9 - (Foo,Bar)|(Ban,Foo) => {}
9 + (Foo,Bar)|(Bar,Foo) => {}
|
```
When encountering an unmet trait bound, point at local type that doesn't implement the trait:
```
error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied
--> $DIR/issue-64855.rs:9:19
|
LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
| ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `Foo` is not implemented for `Bar<T>`
--> $DIR/issue-64855.rs:9:1
|
LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
| ^^^^^^^^^^^^^^^^^
```
Add `FnContext` in parser for diagnostic
Fixesrust-lang/rust#144968
Inspired by https://github.com/rust-lang/rust/issues/144968#issuecomment-3156094581, I implemented `FnContext` to indicate whether a function should have a self parameter, for example, whether the function is a trait method, whether it is in an impl block. And I removed the outdated note.
I made two commits to show the difference.
cc ``@estebank`` ``@djc``
r? compiler
Modify `AttributeTemplate` to support list of alternatives for list and name value attribute styles.
Suggestions now provide more correct suggested code:
```
error[E0805]: malformed `used` attribute input
--> $DIR/used_with_multi_args.rs:3:1
|
LL | #[used(compiler, linker)]
| ^^^^^^------------------^
| |
| expected a single argument here
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[used(compiler, linker)]
LL + #[used(compiler)]
|
LL - #[used(compiler, linker)]
LL + #[used(linker)]
|
LL - #[used(compiler, linker)]
LL + #[used]
|
```
instead of the prior "masking" of the lack of this feature by suggesting pipe-separated lists:
```
error[E0805]: malformed `used` attribute input
--> $DIR/used_with_multi_args.rs:3:1
|
LL | #[used(compiler, linker)]
| ^^^^^^------------------^
| |
| expected a single argument here
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[used(compiler, linker)]
LL + #[used(compiler|linker)]
|
LL - #[used(compiler, linker)]
LL + #[used]
|
```
When encountering a move error involving a closure because the captured value isn't `Copy`, and the obligation comes from a bound on a type parameter that requires `Fn` or `FnMut`, we point at it and explain that an `FnOnce` wouldn't cause the move error.
```
error[E0507]: cannot move out of `foo`, a captured variable in an `Fn` closure
--> f111.rs:15:25
|
14 | fn do_stuff(foo: Option<Foo>) {
| --- ----------- move occurs because `foo` has type `Option<Foo>`, which does not implement the `Copy` trait
| |
| captured outer variable
15 | require_fn_trait(|| async {
| -- ^^^^^ `foo` is moved here
| |
| captured by this `Fn` closure
16 | if foo.map_or(false, |f| f.foo()) {
| --- variable moved due to use in coroutine
|
help: `Fn` and `FnMut` closures require captured values to be able to be consumed multiple times, but an `FnOnce` consume them only once
--> f111.rs:12:53
|
12 | fn require_fn_trait<F: Future<Output = ()>>(_: impl Fn() -> F) {}
| ^^^^^^^^^
help: consider cloning the value if the performance cost is acceptable
|
16 | if foo.clone().map_or(false, |f| f.foo()) {
| ++++++++
```