region errors: suggest new signature
In some cases, we can suggest a new signature where the user introduces a new named lifetime. This is a bit tricky to figure out how to format the suggestion. It would get mildly easier with https://github.com/rust-lang/rfcs/pull/2115.
struct Ref<'a> { x: &'a u32 }
fn foo<T>(mut x: Vec<Ref<T>>, data: u32, y: Ref<T>) {
x.push(y);
}
The old code used to produce a modified form of the HIR to format the suggestion. I'd prefer not to do that. I was thinking we could probably do something simpler where we just emit the "new parts" of the signature, maybe like this?
hint: consider changing the signature as shown:
| fn foo<'a, ...>(mut x: Vec<Ref<'a, T>>, ..., y: Ref<'a, T>)
Idea would be to do something like this:
- Find name for a fresh lifetime that is not in scope (e.g.,
'``a) - Emit
fn - Emit name of function (
foo) - If the function has generic parameters already:
- Emit
<, fresh lifetime,…,>
- Emit
- Else:
- Emit
<, fresh lifetime,>
- Emit
- Emit
( - Emit
…if needed - Emit parameter name 1 and type (with fresh lifetime substituted)
- Emit
…if needed - Emit parameter name 2 and type (with fresh lifetime substituted)
- Emit
…if needed - Emit
)
Not sure if this is a good plan. Might be best to wait until the https://github.com/rust-lang/rfcs/pull/2115 is settled, since that would permit us to make a suggestion where we just add a fresh named lifetime, and we don't have to add <'a> or anything.
Current output:
error[[E0107]](https://doc.rust-lang.org/stable/error_codes/E0107.html): struct takes 0 generic arguments but 1 generic argument was supplied --> src/lib.rs:3:22 | 3 | fn foo<T>(mut x: Vec<Ref<T>>, data: u32, y: Ref<T>) { | ^^^ - help: remove this generic argument | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:1:8 | 1 | struct Ref<'a> { x: &'a u32 } | ^^^ error[[E0107]](https://doc.rust-lang.org/stable/error_codes/E0107.html): struct takes 0 generic arguments but 1 generic argument was supplied --> src/lib.rs:3:45 | 3 | fn foo<T>(mut x: Vec<Ref<T>>, data: u32, y: Ref<T>) { | ^^^ - help: remove this generic argument | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:1:8 | 1 | struct Ref<'a> { x: &'a u32 } | ^^^error: lifetime may not live long enough --> src/lib.rs:4:5 | 3 | fn foo<T>(mut x: Vec<Ref>, data: u32, y: Ref) { | ----- - has type `Ref<'1>` | | | has type `Vec<Ref<'2>>` 4 | x.push(y); | ^^^^^^^^^ argument requires that `'1` must outlive `'2`Esteban Kuber at 2023-08-03 16:59:33