Skip to content

NLL: rewrites should include actual source input, not solely the hypothesized rewrites #52877

Closed
@pnkfelix

Description

While working on #52663, I noticed something I had not seen before: the .nll.stderr files for borrowck-move-out-of-vec-tail.nll.stderr and borrowck-vec-pattern-nesting.nll.stderr have an odd characteristic: they print out highlighted spans that do not actually correspond to the actual input source code, but rather correspond to the hypothetical rewritten code that we are asking the user to type in.


Let me explain with actual pointers to lines in the files:

This is what the .nll.stderr files say we expect to see from the compiler (and what the compiler is actually printing under NLL mode, modulo details like the specific line numbers in the left-hand column):

help: to prevent move, use ref or ref mut
|
LL | &[Foo { string: ref a },
| ^^^^^
help: to prevent move, use ref or ref mut
|
LL | Foo { string: ref b }] => {
| ^^^^^

help: to prevent move, use ref or ref mut
|
LL | &mut [ref _a, _b, _c] => {} //~ ERROR cannot move out
| ^^^^^^
help: to prevent move, use ref or ref mut
|
LL | &mut [_a, ref _b, _c] => {} //~ ERROR cannot move out
| ^^^^^^
help: to prevent move, use ref or ref mut
|
LL | &mut [_a, _b, ref _c] => {} //~ ERROR cannot move out
| ^^^^^^

In the .nll.stderr files that I linked above, the highlighted spans correspond to these lines:

match tail {
&[Foo { string: a },
//~^ ERROR cannot move out of type `[Foo]`
//~| cannot move out
//~| to prevent move
Foo { string: b }] => {

match vec {
&mut [_a, _b, _c] => {} //~ ERROR cannot move out
//~| cannot move out

(Do you see the problem? If not, read on...)


The problem I have with this is that when I see output from rustc like:

here be some code
     ^^

I expect to actually find the actual text here is some code in my source file. If the diagnostic wants to include a suggestion that we replace "be" with "is", then I expect that to appear as help text that says something like "write is instead of be" or even just "write is here" (with the "be" highlighted, as above)

In short, the user experience (at least for me) from the current NLL is a bit frustrating, because when I see the error message, it seems like it is saying "insert a ref here", but then from my point of view it is printing out the source code and my reaction is "there already is a ref there" (because I'm staring at the print-out in the user terminal and not the source code in my text editor).


The fix for this should be simple: identify the cases that are creating these strange diagnostics, and replace them with something more traditional. Note in particular that in both the cases above, the AST-borrowck generated error is more normal:

LL | &[Foo { string: a },
| ^ - hint: to prevent move, use `ref a` or `ref mut a`
| __________________|
| |
LL | | //~^ ERROR cannot move out of type `[Foo]`
LL | | //~| cannot move out
LL | | //~| to prevent move
LL | | Foo { string: b }] => {
| |_________________________________-__^ cannot move out of here
| |
| ...and here (use `ref b` or `ref mut b`)

LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out
| ^--^^--^^--^
| || | |
| || | ...and here (use `ref _c` or `ref mut _c`)
| || ...and here (use `ref _b` or `ref mut _b`)
| |hint: to prevent move, use `ref _a` or `ref mut _a`

However, if someone can point me at at an established precedent for this pattern (lets say at least three examples) in the current rustc, then I would also be willing to accept that this is something we already do and that I am just an old fogie who is unaware of how the UX tide is shifting.

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)NLL-diagnosticsWorking towards the "diagnostic parity" goal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions