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

Teach diagnostics to correct margin of multiline messages #38916

Merged
merged 5 commits into from
Jan 11, 2017

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Jan 8, 2017

Make the suggestion list have a correct padding:

error[E0308]: mismatched types
 --> file.rs:3:20
  |
3 |     let x: usize = "";
  |                    ^^ expected usize, found reference
  |
  = note: expected type `usize`
  = note:    found type `&'static str`
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

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

@estebank estebank force-pushed the pad-suggestion-list branch 2 times, most recently from db5ec8b to 7f7a0dc Compare January 8, 2017 07:24
Make the suggestion list have a correct padding:

```
error[E0308]: mismatched types
 --> file.rs:3:20
  |
3 |     let x: usize = "";
  |                    ^^ expected usize, found reference
  |
  = note: expected type `usize`
  = note:    found type `&'static str`
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()
```
@estebank estebank force-pushed the pad-suggestion-list branch from 7f7a0dc to 43b10fa Compare January 8, 2017 07:34
format!("{}\n{}",
&child.message,
&child.list.iter().map(|item| {
format!("{} - {}",
Copy link
Contributor

Choose a reason for hiding this comment

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

It is hard for to understand the inner loop.
Can you describe 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.

Added comments.

.collect::<String>(),
item)
}).collect::<Vec<String>>()
.join("\n"))
Copy link
Contributor

@KalitaAlexey KalitaAlexey Jan 8, 2017

Choose a reason for hiding this comment

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

Are you sure that collect and join are more efficient than fold?

EDIT:
I think that it is more efficient.

@@ -699,6 +699,7 @@ impl EmitterWriter {
.to_string(),
span: MultiSpan::new(),
render_span: None,
list: vec![],
Copy link
Contributor

@KalitaAlexey KalitaAlexey Jan 8, 2017

Choose a reason for hiding this comment

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

@nikomatsakis,
Is vec![] idiomatic way to create an empty vector?
I mean that vec! is a macro.
It requires expansion.
I think that Vec::new is more appropriate.

@@ -191,11 +197,23 @@ impl Diagnostic {
message: &str,
span: MultiSpan,
render_span: Option<RenderSpan>) {
self.sub_with_list(level, message, span, render_span, vec![]);
Copy link
Contributor

Choose a reason for hiding this comment

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

@nikomatsakis,
Is vec![] idiomatic way to create an empty vector?
I mean that vec! is a macro.
It requires expansion.
I think that Vec::new is more appropriate.

@estebank estebank force-pushed the pad-suggestion-list branch 2 times, most recently from 3d4a19d to a54d700 Compare January 8, 2017 21:11
@estebank estebank force-pushed the pad-suggestion-list branch 2 times, most recently from a934320 to ba7503c Compare January 8, 2017 22:10
@estebank
Copy link
Contributor Author

estebank commented Jan 8, 2017

I realized that this could be generalized in a better way by making the diagnostic renderer aware of multiline strings, and make it provide the appropriate margin instead. By doing it that way

  • the diagnostics do not need to care about lists at all
  • multiline strings now should look much better (not that there're many at this time)
  • the json output remains untouched, showing the unpadded multiline string

@estebank estebank changed the title Teach diagnostics to have correctly padded suggestion lists Teach diagnostics to correct the margin of multiline messages Jan 8, 2017
@estebank estebank changed the title Teach diagnostics to correct the margin of multiline messages Teach diagnostics to correct margin of multiline messages Jan 8, 2017
fn msg_with_padding(&self, msg: &str, padding: usize) -> String {
let padding = (0..padding)
.map(|_| " ")
.collect::<String>();
Copy link
Contributor

Choose a reason for hiding this comment

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

If I get it right, it will allocate every time the method is called.
What do you think about adding a function

fn add_padding(msg: &mut String, padding: usize) {
    for _ in 0..padding {
        msg.push(' ');
    }
}

and using it instead of pushing padding.

}
acc.push_str(&x.1);
acc.push_str("\n");
acc
Copy link
Contributor

Choose a reason for hiding this comment

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

I need other opinions, but I think that before 711 lines you call measure a new string size and reserve it to prevent allocations in 713, 715, 716 lines.

@@ -721,7 +736,10 @@ impl EmitterWriter {
draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
buffer.append(0, &level.to_string(), Style::HeaderMsg);
buffer.append(0, ": ", Style::NoStyle);
buffer.append(0, msg, Style::NoStyle);

// The extra 9 ` ` is the padding that's always needed to align to the `note: `.
Copy link
Contributor

Choose a reason for hiding this comment

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

How about "note".len() + 5 (and "suggestion".len() + 5 further down) to have one magic number instead of two?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Make any diagnostic line to have the correct margin to align with the
first line:

```
error: message
 --> file.rs:3:20
  |
3 |     <CODE>
  |      ^^^^
  |
  = note: this is a multiline
          note with a correct
          margin
  = note: this is a single line note
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()
  = suggestion: this is a multiline
                suggestion with a
                correct margin
```
@estebank estebank force-pushed the pad-suggestion-list branch from ba7503c to b206064 Compare January 9, 2017 00:07
buffer.append(0, msg, Style::NoStyle);

// The extra 3 ` ` is the padding that's always needed to align to the `note: `.
let message = self.msg_with_padding(msg, max_line_num_len + "note: ".len() + 3);
Copy link
Contributor

Choose a reason for hiding this comment

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

What does 3 stand for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

error: message
 --> file.rs:3:20
  |
3 |     <CODE>
  |      ^^^^
  |
  = note: multiline
          message
+^^^------
|  |     |
|  |     length of "note: "
|  the magic `3`
`max_line_num_len`

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nikomatsakis
Copy link
Contributor

@bors r+

This is very nice.

@bors
Copy link
Contributor

bors commented Jan 10, 2017

📌 Commit 04e4a60 has been approved by nikomatsakis

@@ -703,6 +703,40 @@ impl EmitterWriter {
}
}

/// Add a left margin to every line but the first, given a padding length and the label being
/// displayed.
fn msg_with_padding(&self, msg: &str, padding: usize, label: &str) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like the labels attached to a span might also need wrapping, not just notes, right?

But I guess this code is not about "autowrap" but specifically targeting \n that are embedded in a message. I see, carry on.

@bors
Copy link
Contributor

bors commented Jan 11, 2017

⌛ Testing commit 04e4a60 with merge e57f061...

bors added a commit that referenced this pull request Jan 11, 2017
Teach diagnostics to correct margin of multiline messages

Make the suggestion list have a correct padding:

```
error[E0308]: mismatched types
 --> file.rs:3:20
  |
3 |     let x: usize = "";
  |                    ^^ expected usize, found reference
  |
  = note: expected type `usize`
  = note:    found type `&'static str`
  = help: here are some functions which might fulfill your needs:
          - .len()
          - .foo()
          - .bar()
```
@bors
Copy link
Contributor

bors commented Jan 11, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: nikomatsakis
Pushing e57f061 to master...

@bors bors merged commit 04e4a60 into rust-lang:master Jan 11, 2017
@bors bors mentioned this pull request Jan 11, 2017
@estebank estebank deleted the pad-suggestion-list branch November 9, 2023 05:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants