mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Implement multi-line errors
This commit is contained in:
parent
24ace1665a
commit
5616b92e4d
@ -966,6 +966,16 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
|
|||||||
line.starts_with( prefix )
|
line.starts_with( prefix )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A multi-line error will have followup lines which will always
|
||||||
|
// start with one of these strings.
|
||||||
|
fn continuation( line: &str) -> bool {
|
||||||
|
line.starts_with(" expected") ||
|
||||||
|
line.starts_with(" found") ||
|
||||||
|
// 1234
|
||||||
|
// Should have 4 spaces: see issue 18946
|
||||||
|
line.starts_with("(")
|
||||||
|
}
|
||||||
|
|
||||||
// Scan and extract our error/warning messages,
|
// Scan and extract our error/warning messages,
|
||||||
// which look like:
|
// which look like:
|
||||||
// filename:line1:col1: line2:col2: *error:* msg
|
// filename:line1:col1: line2:col2: *error:* msg
|
||||||
@ -981,7 +991,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
|
|||||||
ee.kind,
|
ee.kind,
|
||||||
ee.msg,
|
ee.msg,
|
||||||
line);
|
line);
|
||||||
if prefix_matches(line, prefixes[i].as_slice()) &&
|
if (prefix_matches(line, prefixes[i].as_slice()) || continuation(line)) &&
|
||||||
line.contains(ee.kind.as_slice()) &&
|
line.contains(ee.kind.as_slice()) &&
|
||||||
line.contains(ee.msg.as_slice()) {
|
line.contains(ee.msg.as_slice()) {
|
||||||
found_flags[i] = true;
|
found_flags[i] = true;
|
||||||
|
@ -35,6 +35,7 @@ extern crate flate;
|
|||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate graphviz;
|
extern crate graphviz;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
extern crate regex;
|
||||||
extern crate rustc_llvm;
|
extern crate rustc_llvm;
|
||||||
extern crate rustc_back;
|
extern crate rustc_back;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
|
@ -15,6 +15,8 @@ use metadata::filesearch;
|
|||||||
use session::search_paths::PathKind;
|
use session::search_paths::PathKind;
|
||||||
use util::nodemap::NodeMap;
|
use util::nodemap::NodeMap;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::diagnostic::{self, Emitter};
|
use syntax::diagnostic::{self, Emitter};
|
||||||
@ -71,7 +73,58 @@ impl Session {
|
|||||||
self.diagnostic().handler().fatal(msg)
|
self.diagnostic().handler().fatal(msg)
|
||||||
}
|
}
|
||||||
pub fn span_err(&self, sp: Span, msg: &str) {
|
pub fn span_err(&self, sp: Span, msg: &str) {
|
||||||
self.diagnostic().span_err(sp, msg)
|
// Conditions for enabling multi-line errors:
|
||||||
|
if !msg.contains("mismatched types") &&
|
||||||
|
!msg.contains("type mismatch resolving") &&
|
||||||
|
!msg.contains("if and else have incompatible types") &&
|
||||||
|
!msg.contains("if may be missing an else clause") &&
|
||||||
|
!msg.contains("match arms have incompatible types") &&
|
||||||
|
!msg.contains("structure constructor specifies a structure of type") {
|
||||||
|
return self.diagnostic().span_err(sp, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let first = Regex::new(r"[( ]expected").unwrap();
|
||||||
|
let second = Regex::new(r" found").unwrap();
|
||||||
|
let third = Regex::new(
|
||||||
|
r"\((values differ|lifetime|cyclic type of infinite size)").unwrap();
|
||||||
|
|
||||||
|
let mut new_msg = String::new();
|
||||||
|
let mut head = 0u;
|
||||||
|
|
||||||
|
// Insert `\n` before expected and found.
|
||||||
|
for (pos1, pos2) in first.find_iter(msg).zip(
|
||||||
|
second.find_iter(msg)) {
|
||||||
|
new_msg = new_msg +
|
||||||
|
// A `(` may be preceded by a space and it should be trimmed
|
||||||
|
msg[head..pos1.0].trim_right() + // prefix
|
||||||
|
"\n" + // insert before first
|
||||||
|
&msg[pos1.0..pos1.1] + // insert what first matched
|
||||||
|
&msg[pos1.1..pos2.0] + // between matches
|
||||||
|
"\n " + // insert before second
|
||||||
|
// 123
|
||||||
|
// `expected` is 3 char longer than `found`. To align the types, `found` gets
|
||||||
|
// 3 spaces prepended.
|
||||||
|
&msg[pos2.0..pos2.1]; // insert what second matched
|
||||||
|
|
||||||
|
head = pos2.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut tail = &msg[head..];
|
||||||
|
// Insert `\n` before any remaining messages which match.
|
||||||
|
for pos in third.find_iter(tail).take(1) {
|
||||||
|
// The end of the message may just be wrapped in `()` without `expected`/`found`.
|
||||||
|
// Push this also to a new line and add the final tail after.
|
||||||
|
new_msg = new_msg +
|
||||||
|
// `(` is usually preceded by a space and should be trimmed.
|
||||||
|
tail[..pos.0].trim_right() + // prefix
|
||||||
|
"\n" + // insert before paren
|
||||||
|
&tail[pos.0..]; // append the tail
|
||||||
|
|
||||||
|
tail = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
new_msg.push_str(tail);
|
||||||
|
self.diagnostic().span_err(sp, &new_msg[])
|
||||||
}
|
}
|
||||||
pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
|
pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
|
||||||
self.diagnostic().span_err_with_code(sp, msg, code)
|
self.diagnostic().span_err_with_code(sp, msg, code)
|
||||||
|
Loading…
Reference in New Issue
Block a user