Skip to content

Commit c6ab068

Browse files
committed
Merge pull request #1 from jonathandturner/borrowck-snippet
Add support for elision in structured error messages
2 parents adf715a + ff2868d commit c6ab068

File tree

2 files changed

+125
-23
lines changed

2 files changed

+125
-23
lines changed

src/libsyntax/errors/snippet/mod.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ pub struct RenderedLine {
5555
pub enum RenderedLineKind {
5656
SourceText,
5757
Highlights,
58+
Elision,
5859
}
5960
use self::RenderedLineKind::*;
6061

@@ -98,9 +99,77 @@ impl SnippetData {
9899
}
99100

100101
pub fn render_lines(&self) -> Vec<RenderedLine> {
101-
self.lines.iter()
102-
.flat_map(|line| self.render_line(line))
103-
.collect()
102+
let mut line_groups = vec![];
103+
104+
//Group our lines by those with annotations and those without
105+
let mut lines_iter = self.lines.iter().peekable();
106+
107+
loop {
108+
match lines_iter.next() {
109+
None => break,
110+
Some(line) if line.annotations.is_empty() => {
111+
// Collect unannotated group
112+
let mut unannotated_group : Vec<&Line> = vec![];
113+
114+
unannotated_group.push(line);
115+
116+
loop {
117+
let next_line =
118+
match lines_iter.peek() {
119+
None => break,
120+
Some(x) if !x.annotations.is_empty() => break,
121+
Some(x) => x.clone()
122+
};
123+
124+
unannotated_group.push(next_line);
125+
lines_iter.next();
126+
}
127+
128+
line_groups.push((false, unannotated_group));
129+
}
130+
Some(line) => {
131+
// Collect annotated group
132+
let mut annotated_group : Vec<&Line> = vec![];
133+
134+
annotated_group.push(line);
135+
136+
loop {
137+
let next_line =
138+
match lines_iter.peek() {
139+
None => break,
140+
Some(x) if x.annotations.is_empty() => break,
141+
Some(x) => x.clone()
142+
};
143+
144+
annotated_group.push(next_line);
145+
lines_iter.next();
146+
}
147+
148+
line_groups.push((true, annotated_group));
149+
}
150+
}
151+
}
152+
153+
let mut output = vec![];
154+
for &(is_annotated, ref group) in line_groups.iter() {
155+
if is_annotated {
156+
let mut v: Vec<RenderedLine> =
157+
group.iter().flat_map(|line| self.render_line(line)).collect();
158+
output.append(&mut v);
159+
}
160+
else {
161+
if group.len() > 1 {
162+
output.push(RenderedLine::from((String::from("..."), Elision)));
163+
}
164+
else {
165+
let mut v: Vec<RenderedLine> =
166+
group.iter().flat_map(|line| self.render_line(line)).collect();
167+
output.append(&mut v);
168+
}
169+
}
170+
}
171+
172+
output
104173
}
105174

106175
fn render_line(&self, line: &Line) -> Vec<RenderedLine> {

src/libsyntax/errors/snippet/test.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,8 @@ fn foo() {
128128
kind: Highlights
129129
},
130130
RenderedLine {
131-
text: "",
132-
kind: SourceText
133-
},
134-
RenderedLine {
135-
text: " // Add one more item we forgot to the vector. Silly us.",
136-
kind: SourceText
131+
text: "...",
132+
kind: Elision
137133
},
138134
RenderedLine {
139135
text: " data.push(Data { name: format!(\"Hera\"), id: 66 });",
@@ -144,20 +140,8 @@ fn foo() {
144140
kind: Highlights
145141
},
146142
RenderedLine {
147-
text: "",
148-
kind: SourceText
149-
},
150-
RenderedLine {
151-
text: " // Print everything out.",
152-
kind: SourceText
153-
},
154-
RenderedLine {
155-
text: " println!(\"Name: {:?}\", name);",
156-
kind: SourceText
157-
},
158-
RenderedLine {
159-
text: " println!(\"Data: {:?}\", data);",
160-
kind: SourceText
143+
text: "...",
144+
kind: Elision
161145
},
162146
RenderedLine {
163147
text: "}",
@@ -269,3 +253,52 @@ fn foo() {
269253
]"#);
270254
}
271255

256+
#[test]
257+
fn elide_unnecessary_lines() {
258+
let file_text = r#"
259+
fn foo() {
260+
let mut vec = vec![0, 1, 2];
261+
let mut vec2 = vec;
262+
vec2.push(3);
263+
vec2.push(4);
264+
vec2.push(5);
265+
vec2.push(6);
266+
vec.push(7);
267+
}
268+
"#;
269+
270+
let cm = Rc::new(CodeMap::new());
271+
cm.new_filemap_and_lines("foo.rs", file_text);
272+
let span_vec0 = cm.span_substr(file_text, "vec", 3);
273+
let span_vec1 = cm.span_substr(file_text, "vec", 8);
274+
275+
let mut snippet = SnippetData::new(cm);
276+
snippet.push(span_vec0, Some(format!("`vec` moved here because it has type `collections::vec::Vec<i32>`, which is moved by default")));
277+
snippet.push(span_vec1, Some(format!("use of moved value: `vec`")));
278+
279+
let lines = snippet.render_lines();
280+
println!("{:#?}", lines);
281+
assert_eq!(format!("\n{:#?}", lines), r#"
282+
[
283+
RenderedLine {
284+
text: " let mut vec2 = vec;",
285+
kind: SourceText
286+
},
287+
RenderedLine {
288+
text: " ~~~ `vec` moved here because it has type `collections::vec::Vec<i32>`, which is moved by default",
289+
kind: Highlights
290+
},
291+
RenderedLine {
292+
text: "...",
293+
kind: Elision
294+
},
295+
RenderedLine {
296+
text: " vec.push(7);",
297+
kind: SourceText
298+
},
299+
RenderedLine {
300+
text: " ~~~ use of moved value: `vec`",
301+
kind: Highlights
302+
}
303+
]"#);
304+
}

0 commit comments

Comments
 (0)