Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimize single span suggestions into a label #40851

Merged
merged 7 commits into from
May 2, 2017
Merged

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Mar 27, 2017

changes

14 |     println!("☃{}", tup[0]);
   |                     ^^^^^^
   |
help: to access tuple elements, use tuple indexing syntax as shown
   |     println!("☃{}", tup.0);

into

14 |     println!("☃{}", tup[0]);
   |                     ^^^^^^ to access tuple elements, use `tup.0`

Also makes suggestions explicit in the backend in preparation of adding multiple suggestions to a single diagnostic. Currently that's already possible, but results in a full help message + modified code snippet per suggestion, and has no rate limit (might show 100+ suggestions).

@rust-highfive
Copy link
Collaborator

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 27, 2017

r? @nrc

cc @jonathandturner
cc @petrochenkov

@rust-highfive rust-highfive assigned nrc and unassigned arielb1 Mar 27, 2017
@nrc
Copy link
Member

nrc commented Mar 27, 2017

cc @rust-lang/tools

@nrc
Copy link
Member

nrc commented Mar 27, 2017

This seems like a good idea because it puts the suggestion closer to the problem and because it is using less space. However, I have two worries:

  • how does it look when there is already a label on a span? I feel that it could be confusing having two labels for different things on the same (or similar) spans
  • I think we should be clear about the status of what the compiler is telling us. I.e., what is a problem that must be fixed, and what is a suggestion that doesn't have to be followed. That might be as simple as keeping the note: prefix for the label (and making it green like the out-of-line helps are). But perhaps we can do better than that?

})));
/// See `diagnostic::CodeSuggestion` for more information.
pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self {
assert!(self.suggestion.is_none());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It surprises me that we never have multiple suggestions, but I guess part of your plan is to do this properly in the long run?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Member

@nrc nrc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine, I'd like to wait and hear from others (in particular @jonathandturner ) about the UX of this change before r+ing

substitutes: vec![suggestion],
})));
/// See `diagnostic::CodeSuggestion` for more information.
pub fn span_suggestion(&mut self, sp: Span, msg: &str, suggestion: String) -> &mut Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is worth keeping the Into<MultiSpan> stuff for consistency with the other methods, unless there is a specific reason to remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that using a multispan will panic in the original emitter code

@@ -11,7 +11,6 @@
use CodeSuggestion;
use Level;
use RenderSpan;
use RenderSpan::Suggestion;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove RenderSpan::Suggestion now or is it still used elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it in for keeping the diff small. I convert to it in the emitter and json impls. Wanted to get feedback on a readable diff first

@sophiajt
Copy link
Contributor

Yeah I like the general idea, though I have the same question as @nrc. What does this look like where there's already a primary label?

@@ -2,11 +2,9 @@ error[E0369]: binary operation `+` cannot be applied to type `&'static str`
--> $DIR/issue-39018.rs:12:13
|
12 | let x = "Hello " + "World!";
| ^^^^^^^^
| ^^^^^^^^ `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left: `"Hello ".to_owned()`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Labels, in general, look better then they are short, maybe as long as this

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

, but no longer if possible.
Maybe long labels can be shortened somehow, and super long ones splitted?

Copy link
Contributor

@sophiajt sophiajt Mar 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agreed and good catch. My rule of thumb has been "6 words, only rarely more"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I was considering also doing a length check. Would it be entirely too confusing to add such an arbitrary limit in the emitter? I mean, someone using span_suggestion might be trying to get their suggestion into a label, but the rule is pretty hidden, even if added to the docs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this specific case I'd like to move the detailed description to the error code description and just write "you can fix this by allocating the string on the left: "Hello".to_owned()"

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 28, 2017

Span_label + span_suggestion looks like span_label twice. So you get vertical lines always and ------ if the spans aren't equal.

I wanted to move the note in the string addition error to a label, because it would make more sense there, but that's ugly, since the suggestion works on a different span, and the label isn't behind the ^^^^^^^.

--- a/src/test/ui/span/issue-39018.stderr
+++ b/src/test/ui/span/issue-39018.stderr
@@ -2,9 +2,10 @@ error[E0369]: binary operation `+` cannot be applied to type `&'static str`
   --> $DIR/issue-39018.rs:12:13
    |
 12 |     let x = "Hello " + "World!";
-   |             ^^^^^^^^ `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left: `"Hello ".to_owned()`
-   |
-   = note: `+` can't be used to concatenate two `&str` strings
+   |             ^^^^^^^^-----------
+   |             |
+   |             `+` can't be used to concatenate two `&str` strings
+   |             `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left. `"Hello ".to_owned()`
 
 error[E0369]: binary operation `+` cannot be applied to type `World`
   --> $DIR/issue-39018.rs:17:13

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 28, 2017

I think we should be clear about the status of what the compiler is telling us. I.e., what is a problem that must be fixed, and what is a suggestion that doesn't have to be followed. That might be as simple as keeping the note: prefix for the label (and making it green like the out-of-line helps are). But perhaps we can do better than that?

I believe it is up to the diagnostic author to produce a good message that makes it obvious that it's a suggestion and not a problem. Something like did you mean, try, maybe you meant, ...

@nrc
Copy link
Member

nrc commented Mar 28, 2017

I believe it is up to the diagnostic author to produce a good message that makes it obvious that it's a suggestion and not a problem. Something like did you mean, try, maybe you meant, ...

I think this is too subtle for communicating to the author and relying too much on future devs doing the right thing - it is a bit like designing an API where you are assuming the client will write bug-free code rather than coding defensively in the API.

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 29, 2017

I think this is too subtle for communicating to the author and relying too much on future devs doing the right thing - it is a bit like designing an API where you are assuming the client will write bug-free code rather than coding defensively in the API.

Makes total sense. The extreme variant would be to create an enum, where the suggestion author can choose between

  • did you mean
  • try
  • maybe you meant
  • Custom(&'static str)

which will be prepended before the code snippet. The author can then choose to leave out the main message, or include the main message if it contains some sort of extra information other than "hey this will fix your code" (like an explanation or sth).

By requiring such an enum to be passed to span_suggestion noone can accidentally forget to pass some form of suggestion text.

@bors
Copy link
Contributor

bors commented Mar 30, 2017

☔ The latest upstream changes (presumably #40597) made this pull request unmergeable. Please resolve the merge conflicts.

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 31, 2017

rebased. The only open question is how to ensure that the API enforces that the message will clearly be a suggestion

Possible solutions:

  • add a new enum so the lint author can choose a message
  • always add suggestion: before the label
  • something else?

@nrc
Copy link
Member

nrc commented Apr 3, 2017

always add suggestion: before the label

works for me - it is nice and simple and (IMO) clear to the user. I'd also be happy to use help:, I don't think that has caused confusion in the past and is shorter.

@Mark-Simulacrum Mark-Simulacrum added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 14, 2017
@carols10cents
Copy link
Member

Friendly ping for @oli-obk! This PR misses you! ❤️

@shepmaster
Copy link
Member

Friendly pings for @oli-obk all around! Do you still plan on being able to address the last bit of suggestions?

@oli-obk
Copy link
Contributor Author

oli-obk commented Apr 21, 2017

Yes. But not before next week

@oli-obk
Copy link
Contributor Author

oli-obk commented Apr 25, 2017

I added the help: prefix before all suggestions that are rendered as labels

@carols10cents carols10cents added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 25, 2017
@carols10cents carols10cents assigned sophiajt and unassigned nrc Apr 25, 2017
@carols10cents
Copy link
Member

Reassigning to @jonathandturner for re-review since nrc is out with 👶

@sophiajt
Copy link
Contributor

Trying to remember this one. IIRC - there was some question about how the label handles larger notes. Do we check for the size of the note before we turn it into a label?

// don't display multispans as labels
if sugg.substitutes.len() == 1 &&
// don't display long messages as labels
sugg.msg.split_whitespace().count() < 10 &&
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rules about message length ate defined here. Currently only single line messages with fewer than 10 words are accepted

@oli-obk
Copy link
Contributor Author

oli-obk commented Apr 27, 2017

The travis failure is bogus. One worker simply didn't start.

@carols10cents
Copy link
Member

Logged that failure in our infrastructure tracking of spurious failures and i've restarted the travis build.

@sophiajt
Copy link
Contributor

I'm 👍 on how this looks. Seems like an overall improvement.

Are all the code questions ironed out? If we're good to go, I'll approve.

@oli-obk
Copy link
Contributor Author

oli-obk commented May 1, 2017

There's a cleanup scheduled for a future PR and multiple suggestions also come later. I went through all comments again and can't find any open questions

@sophiajt
Copy link
Contributor

sophiajt commented May 1, 2017

@bors r+

@bors
Copy link
Contributor

bors commented May 1, 2017

📌 Commit d64af4a has been approved by jonathandturner

@bors
Copy link
Contributor

bors commented May 2, 2017

⌛ Testing commit d64af4a with merge 33535af...

bors added a commit that referenced this pull request May 2, 2017
Minimize single span suggestions into a label

changes

```
14 |     println!("☃{}", tup[0]);
   |                     ^^^^^^
   |
help: to access tuple elements, use tuple indexing syntax as shown
   |     println!("☃{}", tup.0);
```

into

```
14 |     println!("☃{}", tup[0]);
   |                     ^^^^^^ to access tuple elements, use `tup.0`
```

Also makes suggestions explicit in the backend in preparation of adding multiple suggestions to a single diagnostic. Currently that's already possible, but results in a full help message + modified code snippet per suggestion, and has no rate limit (might show 100+ suggestions).
@bors
Copy link
Contributor

bors commented May 2, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: jonathandturner
Pushing 33535af to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants