Skip to content

Make -Ztrack-diagnostics emit like a note #143286

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 96 additions & 54 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,7 @@ impl HumanEmitter {
label: &str,
override_style: Option<Style>,
) -> usize {
let line_offset = buffer.num_lines().saturating_sub(1);
// The extra 5 ` ` is padding that's always needed to align to the `note: `:
//
// error: message
Expand Down Expand Up @@ -1447,12 +1448,20 @@ impl HumanEmitter {
for (i, line) in lines.iter().enumerate() {
if i != 0 {
line_number += 1;
buffer.append(line_number, &padding, Style::NoStyle);
buffer.append(line_number + line_offset, &padding, Style::NoStyle);
}
buffer.append(line_number, line, style_or_override(*style, override_style));
buffer.append(
line_number + line_offset,
line,
style_or_override(*style, override_style),
);
}
} else {
buffer.append(line_number, text, style_or_override(*style, override_style));
buffer.append(
line_number + line_offset,
text,
style_or_override(*style, override_style),
);
}
}
line_number
Expand All @@ -1468,40 +1477,21 @@ impl HumanEmitter {
level: &Level,
max_line_num_len: usize,
is_secondary: bool,
emitted_at: Option<&DiagLocation>,
is_cont: bool,
) -> io::Result<()> {
let mut buffer = StyledBuffer::new();

if !msp.has_primary_spans() && !msp.has_span_labels() && is_secondary && !self.short_message
{
// This is a secondary message with no span info
for _ in 0..max_line_num_len {
buffer.prepend(0, " ", Style::NoStyle);
}
self.draw_note_separator(&mut buffer, 0, max_line_num_len + 1, is_cont);
if *level != Level::FailureNote {
buffer.append(0, level.to_str(), Style::MainHeaderMsg);
buffer.append(0, ": ", Style::NoStyle);
}
let printed_lines =
self.msgs_to_buffer(&mut buffer, msgs, args, max_line_num_len, "note", None);
if is_cont && matches!(self.theme, OutputTheme::Unicode) {
// There's another note after this one, associated to the subwindow above.
// We write additional vertical lines to join them:
// ╭▸ test.rs:3:3
// │
// 3 │ code
// │ ━━━━
// │
// ├ note: foo
// │ bar
// ╰ note: foo
// bar
for i in 1..=printed_lines {
self.draw_col_separator_no_space(&mut buffer, i, max_line_num_len + 1);
}
}
self.draw_secondary_message(
&mut buffer,
msgs,
args,
0,
level,
max_line_num_len,
is_cont,
);
} else {
let mut label_width = 0;
// The failure note level itself does not provide any useful diagnostic information
Expand Down Expand Up @@ -1978,12 +1968,6 @@ impl HumanEmitter {
trace!("buffer: {:#?}", buffer.render());
}

if let Some(tracked) = emitted_at {
let track = format!("-Ztrack-diagnostics: created at {tracked}");
let len = buffer.num_lines();
buffer.append(len, &track, Style::NoStyle);
}

// final step: take our styled buffer, render it, then output it
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;

Expand Down Expand Up @@ -2495,34 +2479,56 @@ impl HumanEmitter {
level,
max_line_num_len,
false,
emitted_at,
!children.is_empty()
|| suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden),
emitted_at.is_some()
|| (!children.is_empty()
|| suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden)),
) {
Ok(()) => {
if !children.is_empty()
let mut buffer = StyledBuffer::new();
let primary_span = span.primary_span().unwrap_or_default();
if let (Some(tracked), false) = (emitted_at, primary_span.is_dummy()) {
if !self.short_message {
self.draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
let track = format!("-Ztrack-diagnostics: created at {tracked}");

self.draw_secondary_message(
&mut buffer,
&[(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)],
args,
1,
&Level::Note,
max_line_num_len,
children.first().is_some_and(|c| c.span.primary_spans().is_empty()),
);
}
} else if !children.is_empty()
|| suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden)
{
let mut buffer = StyledBuffer::new();
let line_offest = buffer.num_lines();
if !self.short_message {
if let Some(child) = children.iter().next()
&& child.span.primary_spans().is_empty()
{
// We'll continue the vertical bar to point into the next note.
self.draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1);
self.draw_col_separator_no_space(
&mut buffer,
line_offest,
max_line_num_len + 1,
);
} else {
// We'll close the vertical bar to visually end the code window.
self.draw_col_separator_end(&mut buffer, 0, max_line_num_len + 1);
self.draw_col_separator_end(
&mut buffer,
line_offest,
max_line_num_len + 1,
);
}
}
if let Err(e) = emit_to_destination(
&buffer.render(),
level,
&mut self.dst,
self.short_message,
) {
panic!("failed to emit error: {e}")
}
}
if let Err(e) =
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)
{
panic!("failed to emit error: {e}")
}
if !self.short_message {
for (i, child) in children.iter().enumerate() {
Expand All @@ -2541,7 +2547,6 @@ impl HumanEmitter {
&child.level,
max_line_num_len,
true,
None,
!should_close,
) {
panic!("failed to emit error: {err}");
Expand All @@ -2561,7 +2566,6 @@ impl HumanEmitter {
&Level::Help,
max_line_num_len,
true,
None,
// FIXME: this needs to account for the suggestion type,
// some don't take any space.
i + 1 != suggestions.len(),
Expand Down Expand Up @@ -2740,6 +2744,44 @@ impl HumanEmitter {
*row_num += 1;
}

fn draw_secondary_message(
&self,
buffer: &mut StyledBuffer,
msgs: &[(DiagMessage, Style)],
args: &FluentArgs<'_>,
line: usize,
level: &Level,
max_line_num_len: usize,
is_cont: bool,
) {
// This is a secondary message with no sphan info
for _ in 0..max_line_num_len {
buffer.prepend(line, " ", Style::NoStyle);
}
self.draw_note_separator(buffer, line, max_line_num_len + 1, is_cont);
if *level != Level::FailureNote {
buffer.append(line, level.to_str(), Style::MainHeaderMsg);
buffer.append(line, ": ", Style::NoStyle);
}
let printed_lines = self.msgs_to_buffer(buffer, msgs, args, max_line_num_len, "note", None);
if is_cont && matches!(self.theme, OutputTheme::Unicode) {
// There's another note after this one, associated to the subwindow above.
// We write additional vertical lines to join them:
// ╭▸ test.rs:3:3
// │
// 3 │ code
// │ ━━━━
// │
// ├ note: foo
// │ bar
// ╰ note: foo
// bar
for i in 1 + line..=printed_lines + line {
self.draw_col_separator_no_space(buffer, i, max_line_num_len + 1);
}
}
}

fn underline(&self, is_primary: bool) -> UnderlineParts {
// X0 Y0
// label_start > ┯━━━━ < underline
Expand Down
3 changes: 2 additions & 1 deletion src/tools/clippy/tests/ui/track-diagnostics.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ error[E0308]: mismatched types
|
LL | const S: A = B;
| ^ expected `A`, found `B`
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC

error: aborting due to 1 previous error

Expand Down
3 changes: 2 additions & 1 deletion tests/rustdoc-ui/track-diagnostics.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ error[E0308]: mismatched types
|
LL | pub const S: A = B;
| ^ expected `A`, found `B`
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC

error: aborting due to 1 previous error

Expand Down
8 changes: 5 additions & 3 deletions tests/ui/track-diagnostics/track.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@ error[E0425]: cannot find value `rust` in this scope
|
LL | break rust
| ^^^^ not found in this scope
-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC

error[E0268]: `break` outside of a loop or labeled block
--> $DIR/track.rs:LL:CC
|
LL | break rust
| ^^^^^^^^^^ cannot `break` outside of a loop or labeled block
-Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC

error: internal compiler error: It looks like you're trying to break rust; would you like some ICE?
--> $DIR/track.rs:LL:CC
|
LL | break rust
| ^^^^^^^^^^
-Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC
= note: the compiler expectedly panicked. this is a feature.
= note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675
= note: rustc $VERSION running on $TARGET
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/track-diagnostics/track2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ LL | let _moved @ _from = String::from("foo");
| | |
| | value moved here
| value used here after move
-Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC
help: borrow this binding in the pattern to avoid moving the value
|
LL | let ref _moved @ ref _from = String::from("foo");
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/track-diagnostics/track3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ error[E0422]: cannot find struct, variant or union type `Blah` in this scope
|
LL | let _unimported = Blah { field: u8 };
| ^^^^ not found in this scope
-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC

error[E0423]: expected value, found builtin type `u8`
--> $DIR/track3.rs:LL:CC
|
LL | let _unimported = Blah { field: u8 };
| ^^ not a value
-Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/track-diagnostics/track4.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ error: missing `enum` for enum definition
|
LL | pub onion {
| ^^^^^^^^^
-Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC
help: add `enum` here to parse `onion` as an enum
|
LL | pub enum onion {
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/track-diagnostics/track5.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ error: unexpected closing delimiter: `}`
|
LL | }
| ^ unexpected closing delimiter
-Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC

error: aborting due to 1 previous error

2 changes: 1 addition & 1 deletion tests/ui/track-diagnostics/track6.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ error[E0658]: specialization is unstable
|
LL | default fn bar() {}
| ^^^^^^^^^^^^^^^^^^^
-Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC
|
= note: -Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC
= note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
= help: add `#![feature(specialization)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
Expand Down
Loading