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

Start emitting labels even if their pointed to file is not available locally #104449

Merged
merged 14 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
// Helper closure to print duplicated lines.
let mut flush_last_line = |last_frame, times| {
if let Some((line, span)) = last_frame {
err.span_label(span, &line);
err.span_note(span, &line);
// Don't print [... additional calls ...] if the number of lines is small
if times < 3 {
for _ in 0..times {
err.span_label(span, &line);
err.span_note(span, &line);
}
} else {
err.span_label(
err.span_note(
span,
format!("[... {} additional calls {} ...]", times, &line),
);
Expand Down
18 changes: 3 additions & 15 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_middle::ty::{
};
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_session::Limit;
use rustc_span::{Pos, Span};
use rustc_span::Span;
use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout};

use super::{
Expand Down Expand Up @@ -256,25 +256,13 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
if tcx.def_key(self.instance.def_id()).disambiguated_data.data
== DefPathData::ClosureExpr
{
write!(f, "inside closure")?;
write!(f, "inside closure")
} else {
// Note: this triggers a `good_path_bug` state, which means that if we ever get here
// we must emit a diagnostic. We should never display a `FrameInfo` unless we
// actually want to emit a warning or error to the user.
write!(f, "inside `{}`", self.instance)?;
write!(f, "inside `{}`", self.instance)
}
if !self.span.is_dummy() {
let sm = tcx.sess.source_map();
let lo = sm.lookup_char_pos(self.span.lo());
write!(
f,
" at {}:{}:{}",
sm.filename_for_diagnostics(&lo.file.name),
lo.line,
lo.col.to_usize() + 1
)?;
}
Ok(())
oli-obk marked this conversation as resolved.
Show resolved Hide resolved
})
}
}
Expand Down
140 changes: 81 additions & 59 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use rustc_lint_defs::pluralize;

use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::sync::Lrc;
use rustc_error_messages::FluentArgs;
use rustc_error_messages::{FluentArgs, SpanLabel};
use rustc_span::hygiene::{ExpnKind, MacroKind};
use std::borrow::Cow;
use std::cmp::{max, min, Reverse};
Expand Down Expand Up @@ -773,6 +773,7 @@ impl EmitterWriter {
draw_col_separator_no_space(buffer, line_offset, width_offset - 2);
}

#[instrument(level = "trace", skip(self), ret)]
fn render_source_line(
&self,
buffer: &mut StyledBuffer,
Expand Down Expand Up @@ -804,6 +805,7 @@ impl EmitterWriter {
Some(s) => normalize_whitespace(&s),
None => return Vec::new(),
};
trace!(?source_string);

let line_offset = buffer.num_lines();

Expand Down Expand Up @@ -1323,6 +1325,7 @@ impl EmitterWriter {
}
}

#[instrument(level = "trace", skip(self, args), ret)]
fn emit_message_default(
&mut self,
msp: &MultiSpan,
Expand Down Expand Up @@ -1384,22 +1387,15 @@ impl EmitterWriter {
}
}
let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp);
trace!("{annotated_files:#?}");

// Make sure our primary file comes first
let (primary_lo, sm) = if let (Some(sm), Some(ref primary_span)) =
(self.sm.as_ref(), msp.primary_span().as_ref())
{
if !primary_span.is_dummy() {
(sm.lookup_char_pos(primary_span.lo()), sm)
} else {
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
return Ok(());
}
} else {
let primary_span = msp.primary_span().unwrap_or_default();
let (Some(sm), false) = (self.sm.as_ref(), primary_span.is_dummy()) else {
// If we don't have span information, emit and exit
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
return Ok(());
return emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message);
};
let primary_lo = sm.lookup_char_pos(primary_span.lo());
if let Ok(pos) =
annotated_files.binary_search_by(|x| x.file.name.cmp(&primary_lo.file.name))
{
Expand All @@ -1410,6 +1406,54 @@ impl EmitterWriter {
for annotated_file in annotated_files {
// we can't annotate anything if the source is unavailable.
if !sm.ensure_source_file_source_present(annotated_file.file.clone()) {
if !self.short_message {
// We'll just print an unannotated message.
Copy link
Contributor

Choose a reason for hiding this comment

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

Here is where we'd have to duplicate some of the printing logic for accurate gutter alignment. :-/

Ideally we'd dedup the logic, but it is fine as long as we have test coverage (which we do) and leave a comment in both places reminding us to modify logic in the other.

for (annotation_id, line) in annotated_file.lines.into_iter().enumerate() {
let mut annotations = line.annotations.clone();
annotations.sort_by_key(|a| Reverse(a.start_col));
let mut line_idx = buffer.num_lines();
buffer.append(
line_idx,
&format!(
"{}:{}:{}",
sm.filename_for_diagnostics(&annotated_file.file.name),
sm.doctest_offset_line(&annotated_file.file.name, line.line_index),
annotations[0].start_col + 1,
),
Style::LineAndColumn,
);
if annotation_id == 0 {
buffer.prepend(line_idx, "--> ", Style::LineNumber);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
line_idx += 1;
};
for (i, annotation) in annotations.into_iter().enumerate() {
if let Some(label) = &annotation.label {
let style = if annotation.is_primary {
Style::LabelPrimary
} else {
Style::LabelSecondary
};
if annotation_id == 0 {
buffer.prepend(line_idx, " |", Style::LineNumber);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
line_idx += 1;
buffer.append(line_idx + i, " = note: ", style);
for _ in 0..max_line_num_len {
buffer.prepend(line_idx, " ", Style::NoStyle);
}
} else {
buffer.append(line_idx + i, ": ", style);
}
buffer.append(line_idx + i, label, style);
}
}
}
}
continue;
}

Expand Down Expand Up @@ -1656,6 +1700,7 @@ impl EmitterWriter {
multilines.extend(&to_add);
}
}
trace!("buffer: {:#?}", buffer.render());
}

if let Some(tracked) = emitted_at {
Expand Down Expand Up @@ -1979,6 +2024,7 @@ impl EmitterWriter {
Ok(())
}

#[instrument(level = "trace", skip(self, args, code, children, suggestions))]
fn emit_messages_default(
&mut self,
level: &Level,
Expand Down Expand Up @@ -2209,46 +2255,28 @@ impl FileWithAnnotatedLines {
let mut multiline_annotations = vec![];

if let Some(ref sm) = emitter.source_map() {
for span_label in msp.span_labels() {
let fixup_lo_hi = |span: Span| {
let lo = sm.lookup_char_pos(span.lo());
let mut hi = sm.lookup_char_pos(span.hi());

// Watch out for "empty spans". If we get a span like 6..6, we
// want to just display a `^` at 6, so convert that to
// 6..7. This is degenerate input, but it's best to degrade
// gracefully -- and the parser likes to supply a span like
// that for EOF, in particular.

if lo.col_display == hi.col_display && lo.line == hi.line {
hi.col_display += 1;
}
(lo, hi)
for SpanLabel { span, is_primary, label } in msp.span_labels() {
// If we don't have a useful span, pick the primary span if that exists.
// Worst case we'll just print an error at the top of the main file.
let span = match (span.is_dummy(), msp.primary_span()) {
(_, None) | (false, _) => span,
(true, Some(span)) => span,
};

if span_label.span.is_dummy() {
if let Some(span) = msp.primary_span() {
// if we don't know where to render the annotation, emit it as a note
// on the primary span.

let (lo, hi) = fixup_lo_hi(span);

let ann = Annotation {
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label
.label
.as_ref()
.map(|m| emitter.translate_message(m, args).to_string()),
annotation_type: AnnotationType::Singleline,
};
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
}
continue;
let lo = sm.lookup_char_pos(span.lo());
let mut hi = sm.lookup_char_pos(span.hi());

// Watch out for "empty spans". If we get a span like 6..6, we
// want to just display a `^` at 6, so convert that to
// 6..7. This is degenerate input, but it's best to degrade
// gracefully -- and the parser likes to supply a span like
// that for EOF, in particular.

if lo.col_display == hi.col_display && lo.line == hi.line {
hi.col_display += 1;
}

let (lo, hi) = fixup_lo_hi(span_label.span);
let label = label.as_ref().map(|m| emitter.translate_message(m, args).to_string());

if lo.line != hi.line {
let ml = MultilineAnnotation {
Expand All @@ -2257,23 +2285,17 @@ impl FileWithAnnotatedLines {
line_end: hi.line,
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label
.label
.as_ref()
.map(|m| emitter.translate_message(m, args).to_string()),
is_primary,
label,
overlaps_exactly: false,
};
multiline_annotations.push((lo.file, ml));
} else {
let ann = Annotation {
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label
.label
.as_ref()
.map(|m| emitter.translate_message(m, args).to_string()),
is_primary,
label,
annotation_type: AnnotationType::Singleline,
};
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
Expand Down
16 changes: 10 additions & 6 deletions src/test/ui/borrowck/issue-81899.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-81899.rs:11:5
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| -------------- inside `_CONST` at $DIR/issue-81899.rs:4:24
...
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5
|
note: inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>`
--> $DIR/issue-81899.rs:11:5
|
LL | panic!()
| ^^^^^^^^
| |
| the evaluated program panicked at 'explicit panic', $DIR/issue-81899.rs:11:5
| inside `f::<[closure@$DIR/issue-81899.rs:4:31: 4:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL
note: inside `_CONST`
--> $DIR/issue-81899.rs:4:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
Expand Down
16 changes: 10 additions & 6 deletions src/test/ui/borrowck/issue-88434-minimal-example.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-minimal-example.rs:10:5
|
LL | const _CONST: &() = &f(&|_| {});
| ---------- inside `_CONST` at $DIR/issue-88434-minimal-example.rs:3:22
...
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
|
note: inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>`
--> $DIR/issue-88434-minimal-example.rs:10:5
|
LL | panic!()
| ^^^^^^^^
| |
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-minimal-example.rs:10:5
| inside `f::<[closure@$DIR/issue-88434-minimal-example.rs:3:25: 3:28]>` at $SRC_DIR/std/src/panic.rs:LL:COL
note: inside `_CONST`
--> $DIR/issue-88434-minimal-example.rs:3:22
|
LL | const _CONST: &() = &f(&|_| {});
| ^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| -------------- inside `_CONST` at $DIR/issue-88434-removal-index-should-be-less.rs:3:24
...
LL | panic!()
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
note: inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>`
--> $DIR/issue-88434-removal-index-should-be-less.rs:10:5
|
LL | panic!()
| ^^^^^^^^
| |
| the evaluated program panicked at 'explicit panic', $DIR/issue-88434-removal-index-should-be-less.rs:10:5
| inside `f::<[closure@$DIR/issue-88434-removal-index-should-be-less.rs:3:31: 3:34]>` at $SRC_DIR/std/src/panic.rs:LL:COL
note: inside `_CONST`
--> $DIR/issue-88434-removal-index-should-be-less.rs:3:24
|
LL | const _CONST: &[u8] = &f(&[], |_| {});
| ^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)

note: erroneous constant used
Expand Down
Loading