Always show end line of multiline annotations
```rust error[E0046]: not all trait items implemented, missing: `Item` --> $DIR/issue-23729.rs:20:9 | 20 | impl Iterator for Recurrence { | _________^ starting here... 21 | | //~^ ERROR E0046 22 | | //~| NOTE missing `Item` in implementation 23 | | //~| NOTE `Item` from trait: `type Item;` ... | 36 | | } 37 | | } | |_________^ ...ending here: missing `Item` in implementation | = note: `Item` from trait: `type Item;` ``` instead of ```rust error[E0046]: not all trait items implemented, missing: `Item` --> $DIR/issue-23729.rs:20:9 | 20 | impl Iterator for Recurrence { | ^ missing `Item` in implementation | = note: `Item` from trait: `type Item;` ```
This commit is contained in:
parent
9e84bf8096
commit
4bc7f5b52c
6 changed files with 269 additions and 97 deletions
|
@ -21,6 +21,8 @@ use std::io::prelude::*;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use term;
|
use term;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
/// Emitter trait for emitting errors.
|
/// Emitter trait for emitting errors.
|
||||||
pub trait Emitter {
|
pub trait Emitter {
|
||||||
|
@ -156,15 +158,6 @@ impl EmitterWriter {
|
||||||
}
|
}
|
||||||
let lo = cm.lookup_char_pos(span_label.span.lo);
|
let lo = cm.lookup_char_pos(span_label.span.lo);
|
||||||
let mut hi = cm.lookup_char_pos(span_label.span.hi);
|
let mut hi = cm.lookup_char_pos(span_label.span.hi);
|
||||||
let mut is_minimized = false;
|
|
||||||
|
|
||||||
// If the span is long multi-line, simplify down to the span of one character
|
|
||||||
let max_multiline_span_length = 8;
|
|
||||||
if lo.line != hi.line && (hi.line - lo.line) > max_multiline_span_length {
|
|
||||||
hi.line = lo.line;
|
|
||||||
hi.col = CharPos(lo.col.0 + 1);
|
|
||||||
is_minimized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch out for "empty spans". If we get a span like 6..6, we
|
// 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
|
// want to just display a `^` at 6, so convert that to
|
||||||
|
@ -175,16 +168,7 @@ impl EmitterWriter {
|
||||||
hi.col = CharPos(lo.col.0 + 1);
|
hi.col = CharPos(lo.col.0 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ann = Annotation {
|
let ann_type = if lo.line != hi.line {
|
||||||
start_col: lo.col.0,
|
|
||||||
end_col: hi.col.0,
|
|
||||||
is_primary: span_label.is_primary,
|
|
||||||
label: span_label.label.clone(),
|
|
||||||
annotation_type: AnnotationType::Singleline,
|
|
||||||
};
|
|
||||||
if is_minimized {
|
|
||||||
ann.annotation_type = AnnotationType::Minimized;
|
|
||||||
} else if lo.line != hi.line {
|
|
||||||
let ml = MultilineAnnotation {
|
let ml = MultilineAnnotation {
|
||||||
depth: 1,
|
depth: 1,
|
||||||
line_start: lo.line,
|
line_start: lo.line,
|
||||||
|
@ -194,8 +178,17 @@ impl EmitterWriter {
|
||||||
is_primary: span_label.is_primary,
|
is_primary: span_label.is_primary,
|
||||||
label: span_label.label.clone(),
|
label: span_label.label.clone(),
|
||||||
};
|
};
|
||||||
ann.annotation_type = AnnotationType::Multiline(ml.clone());
|
multiline_annotations.push((lo.file.clone(), ml.clone()));
|
||||||
multiline_annotations.push((lo.file.clone(), ml));
|
AnnotationType::Multiline(ml)
|
||||||
|
} else {
|
||||||
|
AnnotationType::Singleline
|
||||||
|
};
|
||||||
|
let ann = Annotation {
|
||||||
|
start_col: lo.col.0,
|
||||||
|
end_col: hi.col.0,
|
||||||
|
is_primary: span_label.is_primary,
|
||||||
|
label: span_label.label.clone(),
|
||||||
|
annotation_type: ann_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !ann.is_multiline() {
|
if !ann.is_multiline() {
|
||||||
|
@ -233,9 +226,15 @@ impl EmitterWriter {
|
||||||
max_depth = ann.depth;
|
max_depth = ann.depth;
|
||||||
}
|
}
|
||||||
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
|
add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
|
||||||
for line in ann.line_start + 1..ann.line_end {
|
let middle = min(ann.line_start + 4, ann.line_end);
|
||||||
|
for line in ann.line_start + 1..middle {
|
||||||
add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
add_annotation_to_file(&mut output, file, ann.line_end, ann.as_end());
|
add_annotation_to_file(&mut output, file, ann.line_end, ann.as_end());
|
||||||
}
|
}
|
||||||
for file_vec in output.iter_mut() {
|
for file_vec in output.iter_mut() {
|
||||||
|
@ -249,16 +248,11 @@ impl EmitterWriter {
|
||||||
file: Rc<FileMap>,
|
file: Rc<FileMap>,
|
||||||
line: &Line,
|
line: &Line,
|
||||||
width_offset: usize,
|
width_offset: usize,
|
||||||
multiline_depth: usize) {
|
code_offset: usize) -> Vec<(usize, Style)> {
|
||||||
let source_string = file.get_line(line.line_index - 1)
|
let source_string = file.get_line(line.line_index - 1)
|
||||||
.unwrap_or("");
|
.unwrap_or("");
|
||||||
|
|
||||||
let line_offset = buffer.num_lines();
|
let line_offset = buffer.num_lines();
|
||||||
let code_offset = if multiline_depth == 0 {
|
|
||||||
width_offset
|
|
||||||
} else {
|
|
||||||
width_offset + multiline_depth + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// First create the source line we will highlight.
|
// First create the source line we will highlight.
|
||||||
buffer.puts(line_offset, code_offset, &source_string, Style::Quotation);
|
buffer.puts(line_offset, code_offset, &source_string, Style::Quotation);
|
||||||
|
@ -286,7 +280,7 @@ impl EmitterWriter {
|
||||||
// previous borrow of `vec` occurs here
|
// previous borrow of `vec` occurs here
|
||||||
//
|
//
|
||||||
// For this reason, we group the lines into "highlight lines"
|
// For this reason, we group the lines into "highlight lines"
|
||||||
// and "annotations lines", where the highlight lines have the `~`.
|
// and "annotations lines", where the highlight lines have the `^`.
|
||||||
|
|
||||||
// Sort the annotations by (start, end col)
|
// Sort the annotations by (start, end col)
|
||||||
let mut annotations = line.annotations.clone();
|
let mut annotations = line.annotations.clone();
|
||||||
|
@ -410,25 +404,9 @@ impl EmitterWriter {
|
||||||
// If there are no annotations or the only annotations on this line are
|
// If there are no annotations or the only annotations on this line are
|
||||||
// MultilineLine, then there's only code being shown, stop processing.
|
// MultilineLine, then there's only code being shown, stop processing.
|
||||||
if line.annotations.is_empty() || line.annotations.iter()
|
if line.annotations.is_empty() || line.annotations.iter()
|
||||||
.filter(|a| {
|
.filter(|a| !a.is_line()).collect::<Vec<_>>().len() == 0
|
||||||
// Set the multiline annotation vertical lines to the left of
|
|
||||||
// the code in this line.
|
|
||||||
if let AnnotationType::MultilineLine(depth) = a.annotation_type {
|
|
||||||
buffer.putc(line_offset,
|
|
||||||
width_offset + depth - 1,
|
|
||||||
'|',
|
|
||||||
if a.is_primary {
|
|
||||||
Style::UnderlinePrimary
|
|
||||||
} else {
|
|
||||||
Style::UnderlineSecondary
|
|
||||||
});
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}).collect::<Vec<_>>().len() == 0
|
|
||||||
{
|
{
|
||||||
return;
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the colunmn separator.
|
// Write the colunmn separator.
|
||||||
|
@ -483,8 +461,7 @@ impl EmitterWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the vertical lines for multiline spans and for labels that are
|
// Write the vertical lines for labels that are on a different line as the underline.
|
||||||
// on a different line as the underline.
|
|
||||||
//
|
//
|
||||||
// After this we will have:
|
// After this we will have:
|
||||||
//
|
//
|
||||||
|
@ -492,7 +469,7 @@ impl EmitterWriter {
|
||||||
// | __________
|
// | __________
|
||||||
// | | |
|
// | | |
|
||||||
// | |
|
// | |
|
||||||
// 3 | |
|
// 3 |
|
||||||
// 4 | | }
|
// 4 | | }
|
||||||
// | |_
|
// | |_
|
||||||
for &(pos, annotation) in &annotations_position {
|
for &(pos, annotation) in &annotations_position {
|
||||||
|
@ -528,16 +505,6 @@ impl EmitterWriter {
|
||||||
style);
|
style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnnotationType::MultilineLine(depth) => {
|
|
||||||
// the first line will have already be filled when we checked
|
|
||||||
// wether there were any annotations for this line.
|
|
||||||
for p in line_offset + 1..line_offset + line_len + 2 {
|
|
||||||
buffer.putc(p,
|
|
||||||
width_offset + depth - 1,
|
|
||||||
'|',
|
|
||||||
style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,11 +515,11 @@ impl EmitterWriter {
|
||||||
//
|
//
|
||||||
// 2 | fn foo() {
|
// 2 | fn foo() {
|
||||||
// | __________ starting here...
|
// | __________ starting here...
|
||||||
// | | |
|
// | |
|
||||||
// | | something about `foo`
|
// | something about `foo`
|
||||||
// 3 | |
|
// 3 |
|
||||||
// 4 | | }
|
// 4 | }
|
||||||
// | |_ ...ending here: test
|
// | _ ...ending here: test
|
||||||
for &(pos, annotation) in &annotations_position {
|
for &(pos, annotation) in &annotations_position {
|
||||||
let style = if annotation.is_primary {
|
let style = if annotation.is_primary {
|
||||||
Style::LabelPrimary
|
Style::LabelPrimary
|
||||||
|
@ -591,11 +558,11 @@ impl EmitterWriter {
|
||||||
//
|
//
|
||||||
// 2 | fn foo() {
|
// 2 | fn foo() {
|
||||||
// | ____-_____^ starting here...
|
// | ____-_____^ starting here...
|
||||||
// | | |
|
// | |
|
||||||
// | | something about `foo`
|
// | something about `foo`
|
||||||
// 3 | |
|
// 3 |
|
||||||
// 4 | | }
|
// 4 | }
|
||||||
// | |_^ ...ending here: test
|
// | _^ ...ending here: test
|
||||||
for &(_, annotation) in &annotations_position {
|
for &(_, annotation) in &annotations_position {
|
||||||
let (underline, style) = if annotation.is_primary {
|
let (underline, style) = if annotation.is_primary {
|
||||||
('^', Style::UnderlinePrimary)
|
('^', Style::UnderlinePrimary)
|
||||||
|
@ -609,6 +576,20 @@ impl EmitterWriter {
|
||||||
style);
|
style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
annotations_position.iter().filter_map(|&(_, annotation)| {
|
||||||
|
match annotation.annotation_type {
|
||||||
|
AnnotationType::MultilineStart(p) | AnnotationType::MultilineEnd(p) => {
|
||||||
|
let style = if annotation.is_primary {
|
||||||
|
Style::LabelPrimary
|
||||||
|
} else {
|
||||||
|
Style::LabelSecondary
|
||||||
|
};
|
||||||
|
Some((p, style))
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
}).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_multispan_max_line_num(&mut self, msp: &MultiSpan) -> usize {
|
fn get_multispan_max_line_num(&mut self, msp: &MultiSpan) -> usize {
|
||||||
|
@ -902,22 +883,64 @@ impl EmitterWriter {
|
||||||
let buffer_msg_line_offset = buffer.num_lines();
|
let buffer_msg_line_offset = buffer.num_lines();
|
||||||
draw_col_separator_no_space(&mut buffer, buffer_msg_line_offset, max_line_num_len + 1);
|
draw_col_separator_no_space(&mut buffer, buffer_msg_line_offset, max_line_num_len + 1);
|
||||||
|
|
||||||
|
// Contains the vertical lines' positions for active multiline annotations
|
||||||
|
let mut multilines = HashMap::new();
|
||||||
|
|
||||||
// Next, output the annotate source for this file
|
// Next, output the annotate source for this file
|
||||||
for line_idx in 0..annotated_file.lines.len() {
|
for line_idx in 0..annotated_file.lines.len() {
|
||||||
self.render_source_line(&mut buffer,
|
let previous_buffer_line = buffer.num_lines();
|
||||||
annotated_file.file.clone(),
|
|
||||||
&annotated_file.lines[line_idx],
|
|
||||||
3 + max_line_num_len,
|
|
||||||
annotated_file.multiline_depth);
|
|
||||||
|
|
||||||
|
let width_offset = 3 + max_line_num_len;
|
||||||
|
let code_offset = if annotated_file.multiline_depth == 0 {
|
||||||
|
width_offset
|
||||||
|
} else {
|
||||||
|
width_offset + annotated_file.multiline_depth + 1
|
||||||
|
};
|
||||||
|
|
||||||
|
let depths = self.render_source_line(&mut buffer,
|
||||||
|
annotated_file.file.clone(),
|
||||||
|
&annotated_file.lines[line_idx],
|
||||||
|
width_offset,
|
||||||
|
code_offset);
|
||||||
|
|
||||||
|
let mut to_add = HashMap::new();
|
||||||
|
|
||||||
|
for (depth, style) in depths {
|
||||||
|
if multilines.get(&depth).is_some() {
|
||||||
|
multilines.remove(&depth);
|
||||||
|
} else {
|
||||||
|
to_add.insert(depth, style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the multiline annotation vertical lines to the left of
|
||||||
|
// the code in this line.
|
||||||
|
for (depth, style) in &multilines {
|
||||||
|
for line in previous_buffer_line..buffer.num_lines() {
|
||||||
|
draw_multiline_line(&mut buffer,
|
||||||
|
line,
|
||||||
|
width_offset,
|
||||||
|
*depth,
|
||||||
|
*style);
|
||||||
|
}
|
||||||
|
}
|
||||||
// check to see if we need to print out or elide lines that come between
|
// check to see if we need to print out or elide lines that come between
|
||||||
// this annotated line and the next one
|
// this annotated line and the next one.
|
||||||
if line_idx < (annotated_file.lines.len() - 1) {
|
if line_idx < (annotated_file.lines.len() - 1) {
|
||||||
let line_idx_delta = annotated_file.lines[line_idx + 1].line_index -
|
let line_idx_delta = annotated_file.lines[line_idx + 1].line_index -
|
||||||
annotated_file.lines[line_idx].line_index;
|
annotated_file.lines[line_idx].line_index;
|
||||||
if line_idx_delta > 2 {
|
if line_idx_delta > 2 {
|
||||||
let last_buffer_line_num = buffer.num_lines();
|
let last_buffer_line_num = buffer.num_lines();
|
||||||
buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber);
|
buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber);
|
||||||
|
|
||||||
|
// Set the multiline annotation vertical lines on `...` bridging line.
|
||||||
|
for (depth, style) in &multilines {
|
||||||
|
draw_multiline_line(&mut buffer,
|
||||||
|
last_buffer_line_num,
|
||||||
|
width_offset,
|
||||||
|
*depth,
|
||||||
|
*style);
|
||||||
|
}
|
||||||
} else if line_idx_delta == 2 {
|
} else if line_idx_delta == 2 {
|
||||||
let unannotated_line = annotated_file.file
|
let unannotated_line = annotated_file.file
|
||||||
.get_line(annotated_file.lines[line_idx].line_index)
|
.get_line(annotated_file.lines[line_idx].line_index)
|
||||||
|
@ -932,11 +955,21 @@ impl EmitterWriter {
|
||||||
Style::LineNumber);
|
Style::LineNumber);
|
||||||
draw_col_separator(&mut buffer, last_buffer_line_num, 1 + max_line_num_len);
|
draw_col_separator(&mut buffer, last_buffer_line_num, 1 + max_line_num_len);
|
||||||
buffer.puts(last_buffer_line_num,
|
buffer.puts(last_buffer_line_num,
|
||||||
3 + max_line_num_len,
|
code_offset,
|
||||||
&unannotated_line,
|
&unannotated_line,
|
||||||
Style::Quotation);
|
Style::Quotation);
|
||||||
|
|
||||||
|
for (depth, style) in &multilines {
|
||||||
|
draw_multiline_line(&mut buffer,
|
||||||
|
last_buffer_line_num,
|
||||||
|
width_offset,
|
||||||
|
*depth,
|
||||||
|
*style);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multilines.extend(&to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,6 +1118,15 @@ fn draw_note_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
|
||||||
buffer.puts(line, col, "= ", Style::LineNumber);
|
buffer.puts(line, col, "= ", Style::LineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_multiline_line(buffer: &mut StyledBuffer,
|
||||||
|
line: usize,
|
||||||
|
offset: usize,
|
||||||
|
depth: usize,
|
||||||
|
style: Style)
|
||||||
|
{
|
||||||
|
buffer.putc(line, offset + depth - 1, '|', style);
|
||||||
|
}
|
||||||
|
|
||||||
fn num_overlap(a_start: usize, a_end: usize, b_start: usize, b_end:usize, inclusive: bool) -> bool {
|
fn num_overlap(a_start: usize, a_end: usize, b_start: usize, b_end:usize, inclusive: bool) -> bool {
|
||||||
let extra = if inclusive {
|
let extra = if inclusive {
|
||||||
1
|
1
|
||||||
|
|
|
@ -97,9 +97,6 @@ pub enum AnnotationType {
|
||||||
/// Annotation under a single line of code
|
/// Annotation under a single line of code
|
||||||
Singleline,
|
Singleline,
|
||||||
|
|
||||||
/// Annotation under the first character of a multiline span
|
|
||||||
Minimized,
|
|
||||||
|
|
||||||
/// Annotation enclosing the first and last character of a multiline span
|
/// Annotation enclosing the first and last character of a multiline span
|
||||||
Multiline(MultilineAnnotation),
|
Multiline(MultilineAnnotation),
|
||||||
|
|
||||||
|
@ -118,6 +115,9 @@ pub enum AnnotationType {
|
||||||
/// Annotation marking the last character of a fully shown multiline span
|
/// Annotation marking the last character of a fully shown multiline span
|
||||||
MultilineEnd(usize),
|
MultilineEnd(usize),
|
||||||
/// Line at the left enclosing the lines of a fully shown multiline span
|
/// Line at the left enclosing the lines of a fully shown multiline span
|
||||||
|
// Just a placeholder for the drawing algorithm, to know that it shouldn't skip the first 4
|
||||||
|
// and last 2 lines of code. The actual line is drawn in `emit_message_default` and not in
|
||||||
|
// `draw_multiline_line`.
|
||||||
MultilineLine(usize),
|
MultilineLine(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,13 +144,6 @@ pub struct Annotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Annotation {
|
impl Annotation {
|
||||||
pub fn is_minimized(&self) -> bool {
|
|
||||||
match self.annotation_type {
|
|
||||||
AnnotationType::Minimized => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wether this annotation is a vertical line placeholder.
|
/// Wether this annotation is a vertical line placeholder.
|
||||||
pub fn is_line(&self) -> bool {
|
pub fn is_line(&self) -> bool {
|
||||||
if let AnnotationType::MultilineLine(_) = self.annotation_type {
|
if let AnnotationType::MultilineLine(_) = self.annotation_type {
|
||||||
|
|
|
@ -932,3 +932,137 @@ error: foo
|
||||||
|
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn long_snippet() {
|
||||||
|
test_harness(r#"
|
||||||
|
fn foo() {
|
||||||
|
X0 Y0 Z0
|
||||||
|
X1 Y1 Z1
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
X2 Y2 Z2
|
||||||
|
X3 Y3 Z3
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
vec![
|
||||||
|
SpanLabel {
|
||||||
|
start: Position {
|
||||||
|
string: "Y0",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
end: Position {
|
||||||
|
string: "X1",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
label: "`X` is a good letter",
|
||||||
|
},
|
||||||
|
SpanLabel {
|
||||||
|
start: Position {
|
||||||
|
string: "Z1",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
end: Position {
|
||||||
|
string: "Z3",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
label: "`Y` is a good letter too",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
r#"
|
||||||
|
error: foo
|
||||||
|
--> test.rs:3:6
|
||||||
|
|
|
||||||
|
3 | X0 Y0 Z0
|
||||||
|
| ______^ starting here...
|
||||||
|
4 | | X1 Y1 Z1
|
||||||
|
| |____^____- starting here...
|
||||||
|
| ||____|
|
||||||
|
| | ...ending here: `X` is a good letter
|
||||||
|
5 | | 1
|
||||||
|
6 | | 2
|
||||||
|
7 | | 3
|
||||||
|
... |
|
||||||
|
15 | | X2 Y2 Z2
|
||||||
|
16 | | X3 Y3 Z3
|
||||||
|
| |___________- ...ending here: `Y` is a good letter too
|
||||||
|
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn long_snippet_multiple_spans() {
|
||||||
|
test_harness(r#"
|
||||||
|
fn foo() {
|
||||||
|
X0 Y0 Z0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
X1 Y1 Z1
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
X2 Y2 Z2
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
X3 Y3 Z3
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
vec![
|
||||||
|
SpanLabel {
|
||||||
|
start: Position {
|
||||||
|
string: "Y0",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
end: Position {
|
||||||
|
string: "Y3",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
label: "`Y` is a good letter",
|
||||||
|
},
|
||||||
|
SpanLabel {
|
||||||
|
start: Position {
|
||||||
|
string: "Z1",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
end: Position {
|
||||||
|
string: "Z2",
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
label: "`Z` is a good letter too",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
r#"
|
||||||
|
error: foo
|
||||||
|
--> test.rs:3:6
|
||||||
|
|
|
||||||
|
3 | X0 Y0 Z0
|
||||||
|
| ______^ starting here...
|
||||||
|
4 | | 1
|
||||||
|
5 | | 2
|
||||||
|
6 | | 3
|
||||||
|
7 | | X1 Y1 Z1
|
||||||
|
| |_________- starting here...
|
||||||
|
8 | || 4
|
||||||
|
9 | || 5
|
||||||
|
10 | || 6
|
||||||
|
11 | || X2 Y2 Z2
|
||||||
|
| ||__________- ...ending here: `Z` is a good letter too
|
||||||
|
... |
|
||||||
|
15 | | 10
|
||||||
|
16 | | X3 Y3 Z3
|
||||||
|
| |_______^ ...ending here: `Y` is a good letter
|
||||||
|
|
||||||
|
"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@ error[E0046]: not all trait items implemented, missing: `bar`
|
||||||
23 | | //~^ ERROR E0046
|
23 | | //~^ ERROR E0046
|
||||||
24 | | //~| NOTE missing `bar` in implementation
|
24 | | //~| NOTE missing `bar` in implementation
|
||||||
25 | | const bar: u64 = 1;
|
25 | | const bar: u64 = 1;
|
||||||
26 | | //~^ ERROR E0323
|
... |
|
||||||
27 | | //~| NOTE does not match trait
|
|
||||||
28 | | const MY_CONST: u32 = 1;
|
28 | | const MY_CONST: u32 = 1;
|
||||||
29 | | }
|
29 | | }
|
||||||
| |_^ ...ending here: missing `bar` in implementation
|
| |_^ ...ending here: missing `bar` in implementation
|
||||||
|
@ -50,8 +49,7 @@ error[E0046]: not all trait items implemented, missing: `MY_CONST`
|
||||||
34 | | //~^ ERROR E0046
|
34 | | //~^ ERROR E0046
|
||||||
35 | | //~| NOTE missing `MY_CONST` in implementation
|
35 | | //~| NOTE missing `MY_CONST` in implementation
|
||||||
36 | | fn bar(&self) {}
|
36 | | fn bar(&self) {}
|
||||||
37 | | fn MY_CONST() {}
|
... |
|
||||||
38 | | //~^ ERROR E0324
|
|
||||||
39 | | //~| NOTE does not match trait
|
39 | | //~| NOTE does not match trait
|
||||||
40 | | }
|
40 | | }
|
||||||
| |_^ ...ending here: missing `MY_CONST` in implementation
|
| |_^ ...ending here: missing `MY_CONST` in implementation
|
||||||
|
@ -76,8 +74,7 @@ error[E0046]: not all trait items implemented, missing: `bar`
|
||||||
45 | | //~^ ERROR E0046
|
45 | | //~^ ERROR E0046
|
||||||
46 | | //~| NOTE missing `bar` in implementation
|
46 | | //~| NOTE missing `bar` in implementation
|
||||||
47 | | type bar = u64;
|
47 | | type bar = u64;
|
||||||
48 | | //~^ ERROR E0325
|
... |
|
||||||
49 | | //~| NOTE does not match trait
|
|
||||||
50 | | const MY_CONST: u32 = 1;
|
50 | | const MY_CONST: u32 = 1;
|
||||||
51 | | }
|
51 | | }
|
||||||
| |_^ ...ending here: missing `bar` in implementation
|
| |_^ ...ending here: missing `bar` in implementation
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
error[E0046]: not all trait items implemented, missing: `Item`
|
error[E0046]: not all trait items implemented, missing: `Item`
|
||||||
--> $DIR/issue-23729.rs:20:9
|
--> $DIR/issue-23729.rs:20:9
|
||||||
|
|
|
|
||||||
20 | impl Iterator for Recurrence {
|
20 | impl Iterator for Recurrence {
|
||||||
| ^ missing `Item` in implementation
|
| _________^ starting here...
|
||||||
|
21 | | //~^ ERROR E0046
|
||||||
|
22 | | //~| NOTE missing `Item` in implementation
|
||||||
|
23 | | //~| NOTE `Item` from trait: `type Item;`
|
||||||
|
... |
|
||||||
|
36 | | }
|
||||||
|
37 | | }
|
||||||
|
| |_________^ ...ending here: missing `Item` in implementation
|
||||||
|
|
|
|
||||||
= note: `Item` from trait: `type Item;`
|
= note: `Item` from trait: `type Item;`
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
|
||||||
37 | | //~^ ERROR E0046
|
37 | | //~^ ERROR E0046
|
||||||
38 | | //~| NOTE missing `Output` in implementation
|
38 | | //~| NOTE missing `Output` in implementation
|
||||||
39 | | //~| NOTE `Output` from trait: `type Output;`
|
39 | | //~| NOTE `Output` from trait: `type Output;`
|
||||||
40 | | extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype {
|
... |
|
||||||
41 | | Fn::call(&self, (comp,))
|
|
||||||
42 | | }
|
42 | | }
|
||||||
43 | | }
|
43 | | }
|
||||||
| |_^ ...ending here: missing `Output` in implementation
|
| |_^ ...ending here: missing `Output` in implementation
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue