Skip to content

Make deleted code in a suggestion clearer#86532

Merged
bors merged 2 commits into
rust-lang:masterfrom
estebank:delete-suggestion-underline
Aug 11, 2021
Merged

Make deleted code in a suggestion clearer#86532
bors merged 2 commits into
rust-lang:masterfrom
estebank:delete-suggestion-underline

Conversation

@estebank

@estebank estebank commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

Show suggestions that include deletions in a way similar to diff's output.

For changes that do not have deletions, use + as an underline for additions and ~ as an underline for replacements.

For multiline suggestions, we now use ~ in the gutter to signal replacements and + to signal whole line replacements/additions.

In all cases we now use color to highlight the specific spans and snippets.

@rust-highfive

Copy link
Copy Markdown
Contributor

r? @petrochenkov

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 22, 2021
Comment thread src/test/ui/suggestions/match-prev-arm-needing-semi.stderr Outdated
Comment thread src/test/ui/single-use-lifetime/one-use-in-trait-method-argument.stderr Outdated
Comment thread src/test/ui/traits/bound/not-on-struct.stderr Outdated
@Nicholas-Baron

Copy link
Copy Markdown
Contributor

I personally view the narrow end of an arrow as a destination to insert some items.
Thus, the bottom line of that error message would something look like

fn foo(&self, _ : &impl Debug) { }
     \/

However, I do get the choice of /\ from an aesthetic perspective (e.g. looks like the ^).
Another idea may be using red for the /\ to signify deletion, which seems to be a common cross-platform idiom.

@iago-lito

iago-lito commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

Just thinking.. what about making it clearer with underline+overline, to avoid @Nicholas-Baron "insert location" interpretation?

      \/             (* snip! *)
fn next(&mut self)
      /\

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 22, 2021
@jieyouxu

Copy link
Copy Markdown
Member

Adding to the bikeshed...

help: try removing the generic parameter and using `impl Trait` instead
  |
8 |         fn foo(&self, _: &impl Debug) { }
  |              --           ++++++++++

Red for deletions -, green for additions +, perhaps like diffs? This has the advantage of showing clearly what's added and should be easier to compute the width for, though the - symbol is already to highlight.

Screen Shot 2021-06-22 at 20 15 19

Maybe use x to signal deletions?

Screen Shot 2021-06-22 at 20 11 56

Maybe even highlight what the user should try to add?

Screen Shot 2021-06-22 at 20 12 34

@bjorn3

bjorn3 commented Jun 22, 2021

Copy link
Copy Markdown
Member

Maybe even highlight what the user should try to add?

The code used to be the same color as the highlights below it, but was changed to be the default color at some point.

@camsteffen

Copy link
Copy Markdown
Contributor

Another idea:
image

@bjorn3

bjorn3 commented Jun 22, 2021

Copy link
Copy Markdown
Member

That doesn't work without colors. Think about a color blind person or copy pasted error messages.

@camsteffen

Copy link
Copy Markdown
Contributor

I think it works without colors.

 help: try removing the generic parameter and using `impl Trait` instead
   |
 8 |         fn foo(&self, _: &impl Debug){ }
   |              ><          >++++++++++<

@bjorn3

bjorn3 commented Jun 22, 2021

Copy link
Copy Markdown
Member

Oh, the > and < are outside of the inserted range instead of inside. That is somewhat non-obvious.

@estebank

estebank commented Jun 22, 2021

Copy link
Copy Markdown
Contributor Author

The other option is to keep the removed code and give it a red background or color, and a different underline, like was proposed above so that it still works with colorless output:

help: try removing the generic parameter and using `impl Trait` instead
  |
8 |         fn foo<U: Debug>(&self, _: &impl Debug) { }
  |               xxxxxxxxxx            ++++++++++

What we lose with that is the ability to just copy and paste the code from the terminal (although I doubt that's a common occurrence).

@camsteffen

Copy link
Copy Markdown
Contributor

Oh, the > and < are outside of the inserted range instead of inside. That is somewhat non-obvious.

Yeah. On second thought I don't think I would use >+< for inserted code.

I think that >< may be more intuitive than /\ for deleted code. Neither seems clearly better to me.

keep the removed code

I don't like that option personally. I would like the output to show exactly what the code looks like after applying the suggestion. I can compare with the current version of the code in the first error message.

@tlyu

tlyu commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

I think /\ looks too much like a proofreader's mark for insertion, so using it to signify deletion seems like a bad idea. Also, I'm not sure it always renders as a legible arrow or caret type appearance in all likely terminal fonts.

I kind of like >< because it looks like it's pointing to the empty space where the deleted text used to be.

There seems to be a suggestion for electronic texts to use marks including % to signify deletion, because of the visual similarity to the traditional handwritten proofreader's mark. For our case, that would have to go inline with the old text that we're suggesting deleting, which is probably not something we want.

Another possibility is to use inline comments like /* deleted */ to signify the deletion, or even just surround the deleted text with an inline comment. Drawbacks include less familiarity with this style of comment (it doesn't seem to be the prevailing style, and rarely appears in tutorial material) and repetition of the deleted text (if we use the "comment out the deleted text" approach).

@estebank

estebank commented Jun 22, 2021

Copy link
Copy Markdown
Contributor Author

I would like the output to show exactly what the code looks like after applying the suggestion. I can compare with the current version of the code in the first error message.

That's been my personal take, but I've encountered enough people that have gotten confused by it that it's making me reconsider my stance for the projects sake.


The problem I see with using + for the underline is that if we are replacing text it doesn't convey the right message, as we are not informing the user that the replacement occurred. That being said:

Screen Shot 2021-06-22 at 11 04 02 AM


Edit: implemented one of the proposals keeping deletions around (which is buggy, but gives an idea of what it'd look like):

Screen Shot 2021-06-22 at 11 37 11 AM

@camsteffen

Copy link
Copy Markdown
Contributor

The problem I see with using + for the underline is that if we are replacing text it doesn't convey the right message, as we are not informing the user that the replacement occurred.

I'm convinced on that. It looks like diff output but the semantics are different. That's confusing.

@Artoria2e5

Copy link
Copy Markdown
Contributor

While we’re at it with the red mark, maybe a strikethrough can be tried too? The \e[9 stuff, not the Unicode hack.

@estebank

Copy link
Copy Markdown
Contributor Author

While we’re at it with the red mark, maybe a strikethrough can be tried too? The \e[9 stuff, not the Unicode hack.

We use termcolor which doesn't have support to specify strikethrough.

Using unicode, I have this mockup. Please ignore the obvious bugs with color positions:

Screen Shot 2021-06-22 at 11 56 08 AM

I don't know if the strikethrough will help that much.

@tlyu

tlyu commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

While we’re at it with the red mark, maybe a strikethrough can be tried too? The \e[9 stuff, not the Unicode hack.

I think that ANSI terminal strikethrough capability isn't widely supported? Also, I think it's important that any annotations survive copying and pasting, especially because we often ask people to copy and paste full error messages when they ask about compiler errors.

@tlyu

tlyu commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

The problem I see with using + for the underline is that if we are replacing text it doesn't convey the right message, as we are not informing the user that the replacement occurred.

I'm convinced on that. It looks like diff output but the semantics are different. That's confusing.

I agree. Maybe ~ as an underline for changes? (It's similar to the proofreader's mark for transposition, which is a bit of a stretch but close enough, I think.) [edit: also, I think the existing ^ underline for insertions/changes is probably good enough, and it doesn't have the association with diff that + would]

@tlyu

tlyu commented Jun 22, 2021

Copy link
Copy Markdown
Contributor

I would like the output to show exactly what the code looks like after applying the suggestion. I can compare with the current version of the code in the first error message.

That's been my personal take, but I've encountered enough people that have gotten confused by it that it's making me reconsider my stance for the projects sake.

I think if we're going to leave the deleted text inline, I'm leaning toward surrounding it with a /* */ comment.

@estebank

Copy link
Copy Markdown
Contributor Author

Three other options. I'm partial to the second one, but the first one looks easier to understand what's going on.

Screen Shot 2021-06-22 at 4 10 49 PM

Screen Shot 2021-06-22 at 4 17 49 PM

Screen Shot 2021-06-22 at 4 24 11 PM

@estebank

Copy link
Copy Markdown
Contributor Author

Current output for this PR:

Screen Shot 2021-06-22 at 4 58 54 PM

@JohnTitor

Copy link
Copy Markdown
Member

Three other options. I'm partial to the second one, but the first one looks easier to understand what's going on.

I'm worried that how the first looks like with --color=never. The second and the current look nice to me.

@jieyouxu

Copy link
Copy Markdown
Member

Current output for this PR:

Screen Shot 2021-06-22 at 4 58 54 PM

I also like this current output. I would like to summarize some UX considerations presented in the
discussions prior that I believe contributes to good suggestion UX:

  • The replacement suggestion should be valid Rust code (or at least a step towards that
    direction) which guides the user towards a proper solution. This is the case with not leaving the
    removed spans behind in the suggestion.
  • The deletion sigil used (~) corresponds well to spell check errors (squiggly/wave-y underlines)
    commonly used by word processors, editors and browsers to hint that a "suggested replacement" is
    available; this can perhaps be more newcomer-friendly due to familiarity. I also think that
    - might collide with its use to indicate location; can be confusing especially without colors. I
    also agree that + can be ambiguous cf. diffs.

  • Different sigils are used (~ for deletion, ^ for addition) that are able to clearly
    distinguish between additions and deletions without relying on colors (friendly for those who
    are colorblind). For example:
help:  try removing the generic parameter and using `impl Trait` instead
  |
8 |         fn foo  (&self, _: &impl Debug) { }
  |               ~~            ^^^^^^^^^^
  • Simple ASCII characters used without exotic whitespace or other symbols; easy for user to type
    out and copy, wide range of terminal/editor/IDE support. The additional advantage of having
    simpler underlines such as ~~~ and ^^^ is that it should be easier to compute their respective
    spans.
  • The selected sigils also works next to each other reasonably well (contrived example...
    since currently presented mockups don't have addition/deletion spans next to each other):
help:  an interesting error message
  |
2 |     let x: u64 = 0;
  |             ~^

(On a side note, how would the addition/deletion underlines be handled if their spans overlap or
are neighbouring?)

@bjorn3

bjorn3 commented Jun 23, 2021

Copy link
Copy Markdown
Member
help:  an interesting error message
  |
2 |     let x: u64 = 0;
  |             ~^

Gcc uses the exact same squiggles for a different purpose:

<source>: In function 'int square(int)':
<source>:3:18: error: 'foo' was not declared in this scope
    3 |     return num * foo;
      |                  ^~~

or

<source>: In function 'int square(int)':
<source>:5:16: error: no match for 'operator*' (operand types are 'int' and 'Foo')
    5 |     return num * Foo{};
      |            ~~~ ^ ~~~~~
      |            |     |
      |            int   Foo

For reference this is what gcc uses for insertions:

<source>:5:16: error: stray '@' in program
    5 |     return num @ Foo{};
      |                ^
<source>: In function 'int square(int)':
<source>:5:15: error: expected ';' before 'Foo'
    5 |     return num @ Foo{};
      |               ^  ~~~
      |               ;

and clang:

<source>:5:15: error: expected ';' after return statement
    return num @ Foo{};
              ^
              ;
1 error generated.

@iago-lito

Copy link
Copy Markdown
Contributor

I agree with the following principles to stick to:

  • A. Replacement suggestion is valid rust code
    • A.1 If possible well-formatted.
  • B Deletion and insertion can be read without colors, colors is only a bonus.
  • C No fancy unicode chars or terminal strikethrough.
  • D Attach neat semantics to the chars used to delimitate deleted/added/changed regions
    • D.1 Yet don't conflict with usual diff semantics.

Then what about :
regular

With red >< for deletion, blue ~ for edition and green ^ for addition.

The only problem I see is possible overlap, in which case I would only derogate to A.1 and fix the overlap with additional whitespace, e.g.:
Additional whitespace

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 11, 2021
@flip1995

Copy link
Copy Markdown
Member

@estebank blessing the Clippy tests with ./x.py test src/tools/clippy --bless worked for me. Using --stage 2 shouldn't be necessary for this, but that shouldn't be the problem here...

Anyway, here's a gist of the Clippy patch

@estebank

Copy link
Copy Markdown
Contributor Author

@flip1995 thanks for checking! Somehow I changed branches some time back without realizing and that's why --stage 2 --bless wasn't working for me 🤦‍♂️

@bors r=petrochenkov rollup=never p=1

@bors

bors commented Aug 11, 2021

Copy link
Copy Markdown
Collaborator

📌 Commit 657caa5 has been approved by petrochenkov

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 11, 2021
@bors

bors commented Aug 11, 2021

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 657caa5 with merge d8036c085d6934bf52caa7b9ab656f95a31c1616...

@bors

bors commented Aug 11, 2021

Copy link
Copy Markdown
Collaborator

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 11, 2021
@estebank

Copy link
Copy Markdown
Contributor Author

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 11, 2021
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors

bors commented Aug 11, 2021

Copy link
Copy Markdown
Collaborator

⌛ Testing commit 657caa5 with merge ccffcaf...

@bors

bors commented Aug 11, 2021

Copy link
Copy Markdown
Collaborator

☀️ Test successful - checks-actions
Approved by: petrochenkov
Pushing ccffcaf to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 11, 2021
@bors bors merged commit ccffcaf into rust-lang:master Aug 11, 2021
@rustbot rustbot added this to the 1.56.0 milestone Aug 11, 2021
flip1995 pushed a commit to flip1995/rust that referenced this pull request Aug 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

Projects

None yet

Development

Successfully merging this pull request may close these issues.