Skip to content

Rollup of 9 pull requests #61303

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

Closed
wants to merge 34 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a35cdd4
Implement `iter::Sum` and `iter::Product` for `Option`
jtdowney Mar 6, 2019
8c69876
Update stable attribute to be since 1.35.0
Centril Mar 19, 2019
422a4c0
Add improved doc example for Sum<Option<T>>
jtdowney Mar 21, 2019
4d9b9e9
wip nth_back on chunks
Apr 26, 2019
73ca8bc
hopefully working nth_back on chunks
May 1, 2019
5eb0e08
Implement nth_back for RChunks(Exact)(Mut)
timvermeulen May 5, 2019
02a148d
wip nth_back on chunks
Apr 26, 2019
aff83c8
hopefully working nth_back on chunks
May 1, 2019
16223e4
new implementation for nth_back for chunks
wizAmit May 14, 2019
fd15405
fixed merge conflicts
wizAmit May 14, 2019
dc82626
wip nth_back on chunks
Apr 26, 2019
2080b86
hopefully working nth_back on chunks
May 1, 2019
29a103d
wip nth_back on chunks
Apr 26, 2019
9309447
succint implementation
wizAmit May 22, 2019
bcfd1f3
fix merge conflicts
wizAmit May 22, 2019
f1d0829
Add Step::sub_usize
timvermeulen May 4, 2019
f9d328d
sync::Weak::{as,from,into}_raw
vorner May 12, 2019
4f1dcb3
rc::Weak::{as,from,into}_raw
vorner May 19, 2019
96e3fb2
librustc_errors: Move annotation collection to own impl
phansch May 25, 2019
0631d19
Avoid unneeded bug!() call
spastorino May 28, 2019
120ce12
Rename `TraitOrImpl` to `Assoc` and `trait_or_impl` to `assoc`.
eddyb May 28, 2019
03d3290
rustc_codegen_ssa: remove obsolete codegen stats.
eddyb May 28, 2019
29b7c06
rustc_codegen_llvm: remove LLVM instruction count stats.
eddyb May 28, 2019
7fa97c0
rustc_codegen_llvm: rename away the last occurrence of `insn`.
eddyb May 28, 2019
9f8d934
Bump Sum and Product for Option<T> to 1.37
dtolnay May 28, 2019
8e3f003
Rollup merge of #58975 - jtdowney:iter_arith_traits_option, r=dtolnay
Centril May 29, 2019
85c975b
Rollup merge of #60542 - timvermeulen:step_sub_usize, r=scottmcm
Centril May 29, 2019
966e354
Rollup merge of #60555 - timvermeulen:rchunks_nth_back, r=scottmcm
Centril May 29, 2019
c98841b
Rollup merge of #60766 - vorner:weak-into-raw, r=sfackler
Centril May 29, 2019
aad084a
Rollup merge of #61048 - wizAmit:feature/nth_back_chunks, r=scottmcm
Centril May 29, 2019
cd38c8f
Rollup merge of #61191 - phansch:annotate_snippet_refactorings1, r=es…
Centril May 29, 2019
e0bb093
Rollup merge of #61291 - spastorino:avoid-unneeded-bug-call, r=estebank
Centril May 29, 2019
2af35bf
Rollup merge of #61294 - eddyb:no-trait-nor-impl, r=varkor
Centril May 29, 2019
c0142ac
Rollup merge of #61297 - eddyb:forsaken-stats, r=nagisa
Centril May 29, 2019
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
Prev Previous commit
Next Next commit
librustc_errors: Move annotation collection to own impl
Extracted from work on #59346. This moves the annotation collection to
the `FileWithAnnotatedLines` impl to allow re-use in a separate
EmitterWriter.
  • Loading branch information
phansch committed May 28, 2019
commit 96e3fb255bfcae8ce7210985bf75e77335d22580
341 changes: 174 additions & 167 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ impl ColorConfig {
}
}

/// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short`
pub struct EmitterWriter {
dst: Destination,
sm: Option<Lrc<SourceMapperDyn>>,
Expand All @@ -170,7 +171,8 @@ pub struct EmitterWriter {
ui_testing: bool,
}

struct FileWithAnnotatedLines {
#[derive(Debug)]
pub struct FileWithAnnotatedLines {
file: Lrc<SourceFile>,
lines: Vec<Line>,
multiline_depth: usize,
Expand Down Expand Up @@ -221,169 +223,6 @@ impl EmitterWriter {
}
}

fn preprocess_annotations(&mut self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> {
fn add_annotation_to_file(file_vec: &mut Vec<FileWithAnnotatedLines>,
file: Lrc<SourceFile>,
line_index: usize,
ann: Annotation) {

for slot in file_vec.iter_mut() {
// Look through each of our files for the one we're adding to
if slot.file.name == file.name {
// See if we already have a line for it
for line_slot in &mut slot.lines {
if line_slot.line_index == line_index {
line_slot.annotations.push(ann);
return;
}
}
// We don't have a line yet, create one
slot.lines.push(Line {
line_index,
annotations: vec![ann],
});
slot.lines.sort();
return;
}
}
// This is the first time we're seeing the file
file_vec.push(FileWithAnnotatedLines {
file,
lines: vec![Line {
line_index,
annotations: vec![ann],
}],
multiline_depth: 0,
});
}

let mut output = vec![];
let mut multiline_annotations = vec![];

if let Some(ref sm) = self.sm {
for span_label in msp.span_labels() {
if span_label.span.is_dummy() {
continue;
}

let lo = sm.lookup_char_pos(span_label.span.lo());
let mut hi = sm.lookup_char_pos(span_label.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 ann_type = if lo.line != hi.line {
let ml = MultilineAnnotation {
depth: 1,
line_start: lo.line,
line_end: hi.line,
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label.label.clone(),
overlaps_exactly: false,
};
multiline_annotations.push((lo.file.clone(), ml.clone()));
AnnotationType::Multiline(ml)
} else {
AnnotationType::Singleline
};
let ann = Annotation {
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label.label.clone(),
annotation_type: ann_type,
};

if !ann.is_multiline() {
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
}
}
}

// Find overlapping multiline annotations, put them at different depths
multiline_annotations.sort_by_key(|&(_, ref ml)| (ml.line_start, ml.line_end));
for item in multiline_annotations.clone() {
let ann = item.1;
for item in multiline_annotations.iter_mut() {
let ref mut a = item.1;
// Move all other multiline annotations overlapping with this one
// one level to the right.
if !(ann.same_span(a)) &&
num_overlap(ann.line_start, ann.line_end, a.line_start, a.line_end, true)
{
a.increase_depth();
} else if ann.same_span(a) && &ann != a {
a.overlaps_exactly = true;
} else {
break;
}
}
}

let mut max_depth = 0; // max overlapping multiline spans
for (file, ann) in multiline_annotations {
if ann.depth > max_depth {
max_depth = ann.depth;
}
let mut end_ann = ann.as_end();
if !ann.overlaps_exactly {
// avoid output like
//
// | foo(
// | _____^
// | |_____|
// | || bar,
// | || );
// | || ^
// | ||______|
// | |______foo
// | baz
//
// and instead get
//
// | foo(
// | _____^
// | | bar,
// | | );
// | | ^
// | | |
// | |______foo
// | baz
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
// 4 is the minimum vertical length of a multiline span when presented: two lines
// of code and two lines of underline. This is not true for the special case where
// the beginning doesn't have an underline, but the current logic seems to be
// working correctly.
let middle = min(ann.line_start + 4, ann.line_end);
for line in ann.line_start + 1..middle {
// Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`).
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
}
if middle < ann.line_end - 1 {
for line in ann.line_end - 1..ann.line_end {
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
}
}
} else {
end_ann.annotation_type = AnnotationType::Singleline;
}
add_annotation_to_file(&mut output, file, ann.line_end, end_ann);
}
for file_vec in output.iter_mut() {
file_vec.multiline_depth = max_depth;
}
output
}

fn render_source_line(&self,
buffer: &mut StyledBuffer,
file: Lrc<SourceFile>,
Expand Down Expand Up @@ -1093,9 +932,7 @@ impl EmitterWriter {
}
}

// Preprocess all the annotations so that they are grouped by file and by line number
// This helps us quickly iterate over the whole message (including secondary file spans)
let mut annotated_files = self.preprocess_annotations(msp);
let mut annotated_files = FileWithAnnotatedLines::collect_annotations(msp, &self.sm);

// Make sure our primary file comes first
let (primary_lo, sm) = if let (Some(sm), Some(ref primary_span)) =
Expand Down Expand Up @@ -1503,6 +1340,176 @@ impl EmitterWriter {
}
}

impl FileWithAnnotatedLines {
/// Preprocess all the annotations so that they are grouped by file and by line number
/// This helps us quickly iterate over the whole message (including secondary file spans)
pub fn collect_annotations(
msp: &MultiSpan,
source_map: &Option<Lrc<SourceMapperDyn>>
) -> Vec<FileWithAnnotatedLines> {
fn add_annotation_to_file(file_vec: &mut Vec<FileWithAnnotatedLines>,
file: Lrc<SourceFile>,
line_index: usize,
ann: Annotation) {

for slot in file_vec.iter_mut() {
// Look through each of our files for the one we're adding to
if slot.file.name == file.name {
// See if we already have a line for it
for line_slot in &mut slot.lines {
if line_slot.line_index == line_index {
line_slot.annotations.push(ann);
return;
}
}
// We don't have a line yet, create one
slot.lines.push(Line {
line_index,
annotations: vec![ann],
});
slot.lines.sort();
return;
}
}
// This is the first time we're seeing the file
file_vec.push(FileWithAnnotatedLines {
file,
lines: vec![Line {
line_index,
annotations: vec![ann],
}],
multiline_depth: 0,
});
}

let mut output = vec![];
let mut multiline_annotations = vec![];

if let Some(ref sm) = source_map {
for span_label in msp.span_labels() {
if span_label.span.is_dummy() {
continue;
}

let lo = sm.lookup_char_pos(span_label.span.lo());
let mut hi = sm.lookup_char_pos(span_label.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 ann_type = if lo.line != hi.line {
let ml = MultilineAnnotation {
depth: 1,
line_start: lo.line,
line_end: hi.line,
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label.label.clone(),
overlaps_exactly: false,
};
multiline_annotations.push((lo.file.clone(), ml.clone()));
AnnotationType::Multiline(ml)
} else {
AnnotationType::Singleline
};
let ann = Annotation {
start_col: lo.col_display,
end_col: hi.col_display,
is_primary: span_label.is_primary,
label: span_label.label.clone(),
annotation_type: ann_type,
};

if !ann.is_multiline() {
add_annotation_to_file(&mut output, lo.file, lo.line, ann);
}
}
}

// Find overlapping multiline annotations, put them at different depths
multiline_annotations.sort_by_key(|&(_, ref ml)| (ml.line_start, ml.line_end));
for item in multiline_annotations.clone() {
let ann = item.1;
for item in multiline_annotations.iter_mut() {
let ref mut a = item.1;
// Move all other multiline annotations overlapping with this one
// one level to the right.
if !(ann.same_span(a)) &&
num_overlap(ann.line_start, ann.line_end, a.line_start, a.line_end, true)
{
a.increase_depth();
} else if ann.same_span(a) && &ann != a {
a.overlaps_exactly = true;
} else {
break;
}
}
}

let mut max_depth = 0; // max overlapping multiline spans
for (file, ann) in multiline_annotations {
if ann.depth > max_depth {
max_depth = ann.depth;
}
let mut end_ann = ann.as_end();
if !ann.overlaps_exactly {
// avoid output like
//
// | foo(
// | _____^
// | |_____|
// | || bar,
// | || );
// | || ^
// | ||______|
// | |______foo
// | baz
//
// and instead get
//
// | foo(
// | _____^
// | | bar,
// | | );
// | | ^
// | | |
// | |______foo
// | baz
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
// 4 is the minimum vertical length of a multiline span when presented: two lines
// of code and two lines of underline. This is not true for the special case where
// the beginning doesn't have an underline, but the current logic seems to be
// working correctly.
let middle = min(ann.line_start + 4, ann.line_end);
for line in ann.line_start + 1..middle {
// Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`).
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
}
if middle < ann.line_end - 1 {
for line in ann.line_end - 1..ann.line_end {
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
}
}
} else {
end_ann.annotation_type = AnnotationType::Singleline;
}
add_annotation_to_file(&mut output, file, ann.line_end, end_ann);
}
for file_vec in output.iter_mut() {
file_vec.multiline_depth = max_depth;
}
output
}
}

fn draw_col_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
buffer.puts(line, col, "| ", Style::LineNumber);
}
Expand Down