struct MyStruct<T> {
x: Option<T>,
}
fn foo<T>(s: &MyStruct<T>) {
match s.x {
Some(_a) => {}
None => {}
}
}
This suggests using ref:
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:8:11
|
8 | match s.x {
| ^ cannot move out of borrowed content
9 | Some(_a) => {}
| -- hint: to prevent move, use `ref _a` or `ref mut _a`
With match ergonomics now stable, it would be better to instead suggest borrowing the field:
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:8:11
|
8 | match s.x {
| ^ cannot move out of borrowed content
| - hint: to prevent move, use `&s.x` or `&mut s.x`
To help people move away from needing to know that ref exists.
(Context that lead me to open this: https://discordapp.com/channels/273534239310479360/274215136414400513/468303728986816512)
cc @ashtneoi
Yeah, I can probably tackle this.
For something like this...
error[E0507]: cannot move out of borrowed content
--> src/main.rs:12:11
|
12 | fn bar<T>(&MyStruct { x: _a }: &MyStruct<T>) { }
| ^^^^^^^^^^^^^^^--^^
| | |
| | hint: to prevent move, use `ref _a` or `ref mut _a`
| cannot move out of borrowed content
...should it suggest changing the type, the pattern (which might be tricky, idk), or neither?
@ashtneoi My personal goal is to have the compiler never mention ref, so I'd hope for it to suggest
fn bar<T>(MyStruct { x: _a }: &MyStruct<T>)
...but I have no idea how hard that might be.
...Can we lint against top-level type declarations like that? It's really confusing trying to figure out the type of _a.
Oh, one more question (sorry): In a lot of cases, NLL already has better suggestions. Should I bother fixing the non-NLL suggestions or just focus on NLL assuming it'll land sometime soon?
Oh, good point; I didn't try NLL. Only fixing the NLL ones sounds like a smart plan.
It took a ton of reading (which is why I'm only now figuring it out), but I managed to put each binding's top-level pattern span into the LocalDecl's VarBindingForm. That means it's definitely feasible to suggest a change to the entire pattern (rather than just the binding site or the RHS value). Things should be easier from here on and I'll hopefully have a PR in a few days.
Current output:
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:8:11
|
8 | match s.x {
| ^^^
| |
| cannot move out of borrowed content
| help: consider borrowing here: `&s.x`
9 | Some(_a) => {}
| -- data moved here
|
note: move occurs because `_a` has type `T`, which does not implement the `Copy` trait
--> src/lib.rs:9:14
|
9 | Some(_a) => {}
| ^^
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:14:11
|
14 | fn bar<T>(&MyStruct { x: _a }: &MyStruct<T>) { }
| ^^^^^^^^^^^^^^^--^^
| | |
| | data moved here
| cannot move out of borrowed content
| help: consider removing the `&`: `MyStruct { x: _a }`
|
note: move occurs because `_a` has type `std::option::Option<T>`, which does not implement the `Copy` trait
--> src/lib.rs:14:26
|
14 | fn bar<T>(&MyStruct { x: _a }: &MyStruct<T>) { }
| ^^
This looks great! Thanks @ashtneoi!
Most helpful comment
It took a ton of reading (which is why I'm only now figuring it out), but I managed to put each binding's top-level pattern span into the
LocalDecl'sVarBindingForm. That means it's definitely feasible to suggest a change to the entire pattern (rather than just the binding site or the RHS value). Things should be easier from here on and I'll hopefully have a PR in a few days.