Skip to content

Commit da86a33

Browse files
committed
---
yaml --- r: 275899 b: refs/heads/borrowck-snippet c: d1038da h: refs/heads/master i: 275897: 45cff01 275895: 38ead03
1 parent aa7f78d commit da86a33

File tree

64 files changed

+607
-475
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+607
-475
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ refs/tags/1.5.0: d8027afc009e55fb07776831094a13b1b64b6305
3939
refs/tags/1.6.0: 4fe6048e8dd100ec1c61a020d01f75046b42e818
4040
refs/tags/1.7.0: 2d2a9311cbe05eb47960489259e1e9408062c863
4141
refs/tags/1.8.0: 6bef00072dbaa86da9dc73b09f926cf67c696b39
42-
refs/heads/borrowck-snippet: 478a33dabc4e6f2f501f476c79b56178d9df4f37
42+
refs/heads/borrowck-snippet: d1038dabc3ca0522035871c12fc46121a92e4028

branches/borrowck-snippet/mk/crates.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
128128
test rustc_lint rustc_const_eval
129129

130130

131-
TOOL_DEPS_compiletest := test getopts log
131+
TOOL_DEPS_compiletest := test getopts log serialize
132132
TOOL_DEPS_rustdoc := rustdoc
133133
TOOL_DEPS_rustc := rustc_driver
134134
TOOL_DEPS_rustbook := std rustdoc
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use errors::{Error, ErrorKind};
12+
use rustc_serialize::json;
13+
use std::str::FromStr;
14+
15+
// These structs are a subset of the ones found in
16+
// `syntax::errors::json`.
17+
18+
#[derive(RustcEncodable, RustcDecodable)]
19+
struct Diagnostic {
20+
message: String,
21+
code: Option<DiagnosticCode>,
22+
level: String,
23+
spans: Vec<DiagnosticSpan>,
24+
children: Vec<Diagnostic>,
25+
rendered: Option<String>,
26+
}
27+
28+
#[derive(RustcEncodable, RustcDecodable, Clone)]
29+
struct DiagnosticSpan {
30+
file_name: String,
31+
line_start: usize,
32+
line_end: usize,
33+
column_start: usize,
34+
column_end: usize,
35+
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
36+
}
37+
38+
#[derive(RustcEncodable, RustcDecodable, Clone)]
39+
struct DiagnosticSpanMacroExpansion {
40+
/// span where macro was applied to generate this code
41+
span: DiagnosticSpan,
42+
43+
/// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]")
44+
macro_decl_name: String,
45+
}
46+
47+
#[derive(RustcEncodable, RustcDecodable, Clone)]
48+
struct DiagnosticCode {
49+
/// The code itself.
50+
code: String,
51+
/// An explanation for the code.
52+
explanation: Option<String>,
53+
}
54+
55+
pub fn parse_output(file_name: &str, output: &str) -> Vec<Error> {
56+
output.lines()
57+
.flat_map(|line| parse_line(file_name, line))
58+
.collect()
59+
}
60+
61+
fn parse_line(file_name: &str, line: &str) -> Vec<Error> {
62+
// The compiler sometimes intermingles non-JSON stuff into the
63+
// output. This hack just skips over such lines. Yuck.
64+
if line.chars().next() == Some('{') {
65+
match json::decode::<Diagnostic>(line) {
66+
Ok(diagnostic) => {
67+
let mut expected_errors = vec![];
68+
push_expected_errors(&mut expected_errors, &diagnostic, file_name);
69+
expected_errors
70+
}
71+
Err(error) => {
72+
println!("failed to decode compiler output as json: `{}`", error);
73+
panic!("failed to decode compiler output as json");
74+
}
75+
}
76+
} else {
77+
vec![]
78+
}
79+
}
80+
81+
fn push_expected_errors(expected_errors: &mut Vec<Error>,
82+
diagnostic: &Diagnostic,
83+
file_name: &str) {
84+
// We only consider messages pertaining to the current file.
85+
let matching_spans =
86+
|| diagnostic.spans.iter().filter(|span| span.file_name == file_name);
87+
let with_code =
88+
|span: &DiagnosticSpan, text: &str| match diagnostic.code {
89+
Some(ref code) =>
90+
// FIXME(#33000) -- it'd be better to use a dedicated
91+
// UI harness than to include the line/col number like
92+
// this, but some current tests rely on it.
93+
//
94+
// Note: Do NOT include the filename. These can easily
95+
// cause false matches where the expected message
96+
// appears in the filename, and hence the message
97+
// changes but the test still passes.
98+
format!("{}:{}: {}:{}: {} [{}]",
99+
span.line_start, span.column_start,
100+
span.line_end, span.column_end,
101+
text, code.code.clone()),
102+
None =>
103+
// FIXME(#33000) -- it'd be better to use a dedicated UI harness
104+
format!("{}:{}: {}:{}: {}",
105+
span.line_start, span.column_start,
106+
span.line_end, span.column_end,
107+
text),
108+
};
109+
110+
// Convert multi-line messages into multiple expected
111+
// errors. We expect to replace these with something
112+
// more structured shortly anyhow.
113+
let mut message_lines = diagnostic.message.lines();
114+
if let Some(first_line) = message_lines.next() {
115+
for span in matching_spans() {
116+
let msg = with_code(span, first_line);
117+
let kind = ErrorKind::from_str(&diagnostic.level).ok();
118+
expected_errors.push(
119+
Error {
120+
line_num: span.line_start,
121+
kind: kind,
122+
msg: msg,
123+
}
124+
);
125+
}
126+
}
127+
for next_line in message_lines {
128+
for span in matching_spans() {
129+
expected_errors.push(
130+
Error {
131+
line_num: span.line_start,
132+
kind: None,
133+
msg: with_code(span, next_line),
134+
}
135+
);
136+
}
137+
}
138+
139+
// If the message has a suggestion, register that.
140+
if let Some(ref rendered) = diagnostic.rendered {
141+
let start_line = matching_spans().map(|s| s.line_start).min().expect("\
142+
every suggestion should have at least one span");
143+
for (index, line) in rendered.lines().enumerate() {
144+
expected_errors.push(
145+
Error {
146+
line_num: start_line + index,
147+
kind: Some(ErrorKind::Suggestion),
148+
msg: line.to_string()
149+
}
150+
);
151+
}
152+
}
153+
154+
// Add notes for the backtrace
155+
for span in matching_spans() {
156+
for frame in &span.expansion {
157+
push_backtrace(expected_errors,
158+
frame,
159+
file_name);
160+
}
161+
}
162+
163+
// Flatten out the children.
164+
for child in &diagnostic.children {
165+
push_expected_errors(expected_errors, child, file_name);
166+
}
167+
}
168+
169+
fn push_backtrace(expected_errors: &mut Vec<Error>,
170+
expansion: &DiagnosticSpanMacroExpansion,
171+
file_name: &str) {
172+
if expansion.span.file_name == file_name {
173+
expected_errors.push(
174+
Error {
175+
line_num: expansion.span.line_start,
176+
kind: Some(ErrorKind::Note),
177+
msg: format!("in this expansion of {}", expansion.macro_decl_name),
178+
}
179+
);
180+
}
181+
182+
for previous_expansion in &expansion.span.expansion {
183+
push_backtrace(expected_errors, previous_expansion, file_name);
184+
}
185+
}

branches/borrowck-snippet/src/libsyntax/codemap.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,56 @@ impl CodeMap {
13941394
pub fn count_lines(&self) -> usize {
13951395
self.files.borrow().iter().fold(0, |a, f| a + f.count_lines())
13961396
}
1397+
1398+
pub fn macro_backtrace(&self, span: Span) -> Vec<MacroBacktrace> {
1399+
let mut last_span = DUMMY_SP;
1400+
let mut span = span;
1401+
let mut result = vec![];
1402+
loop {
1403+
let span_name_span = self.with_expn_info(span.expn_id, |expn_info| {
1404+
expn_info.map(|ei| {
1405+
let (pre, post) = match ei.callee.format {
1406+
MacroAttribute(..) => ("#[", "]"),
1407+
MacroBang(..) => ("", "!"),
1408+
};
1409+
let macro_decl_name = format!("{}{}{}",
1410+
pre,
1411+
ei.callee.name(),
1412+
post);
1413+
let def_site_span = ei.callee.span;
1414+
(ei.call_site, macro_decl_name, def_site_span)
1415+
})
1416+
});
1417+
1418+
match span_name_span {
1419+
None => break,
1420+
Some((call_site, macro_decl_name, def_site_span)) => {
1421+
// Don't print recursive invocations
1422+
if !call_site.source_equal(&last_span) {
1423+
result.push(MacroBacktrace {
1424+
call_site: call_site,
1425+
macro_decl_name: macro_decl_name,
1426+
def_site_span: def_site_span,
1427+
});
1428+
}
1429+
last_span = span;
1430+
span = call_site;
1431+
}
1432+
}
1433+
}
1434+
result
1435+
}
1436+
}
1437+
1438+
pub struct MacroBacktrace {
1439+
/// span where macro was applied to generate this code
1440+
pub call_site: Span,
1441+
1442+
/// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]")
1443+
pub macro_decl_name: String,
1444+
1445+
/// span where macro was defined (if known)
1446+
pub def_site_span: Option<Span>,
13971447
}
13981448

13991449
// _____________________________________________________________________________

branches/borrowck-snippet/src/libsyntax/errors/emitter.rs

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -577,46 +577,17 @@ impl EmitterWriter {
577577
fn print_macro_backtrace(&mut self,
578578
sp: Span)
579579
-> io::Result<()> {
580-
let mut last_span = codemap::DUMMY_SP;
581-
let mut span = sp;
582-
583-
loop {
584-
let span_name_span = self.cm.with_expn_info(span.expn_id, |expn_info| {
585-
expn_info.map(|ei| {
586-
let (pre, post) = match ei.callee.format {
587-
codemap::MacroAttribute(..) => ("#[", "]"),
588-
codemap::MacroBang(..) => ("", "!"),
589-
};
590-
let macro_decl_name = format!("in this expansion of {}{}{}",
591-
pre,
592-
ei.callee.name(),
593-
post);
594-
let def_site_span = ei.callee.span;
595-
(ei.call_site, macro_decl_name, def_site_span)
596-
})
597-
});
598-
let (macro_decl_name, def_site_span) = match span_name_span {
599-
None => break,
600-
Some((sp, macro_decl_name, def_site_span)) => {
601-
span = sp;
602-
(macro_decl_name, def_site_span)
603-
}
604-
};
605-
606-
// Don't print recursive invocations
607-
if !span.source_equal(&last_span) {
608-
let mut diag_string = macro_decl_name;
609-
if let Some(def_site_span) = def_site_span {
610-
diag_string.push_str(&format!(" (defined in {})",
611-
self.cm.span_to_filename(def_site_span)));
612-
}
613-
614-
let snippet = self.cm.span_to_string(span);
615-
print_diagnostic(&mut self.dst, &snippet, Note, &diag_string, None)?;
580+
for trace in self.cm.macro_backtrace(sp) {
581+
let mut diag_string =
582+
format!("in this expansion of {}", trace.macro_decl_name);
583+
if let Some(def_site_span) = trace.def_site_span {
584+
diag_string.push_str(
585+
&format!(" (defined in {})",
586+
self.cm.span_to_filename(def_site_span)));
616587
}
617-
last_span = span;
588+
let snippet = self.cm.span_to_string(sp);
589+
print_diagnostic(&mut self.dst, &snippet, Note, &diag_string, None)?;
618590
}
619-
620591
Ok(())
621592
}
622593
}

0 commit comments

Comments
 (0)