Skip to content
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

Multi-line errors #19870

Merged
merged 3 commits into from
Jan 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,16 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
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,
// which look like:
// filename:line1:col1: line2:col2: *error:* msg
Expand All @@ -981,7 +991,7 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
ee.kind,
ee.msg,
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.msg.as_slice()) {
found_flags[i] = true;
Expand Down
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extern crate flate;
extern crate getopts;
extern crate graphviz;
extern crate libc;
extern crate regex;
extern crate rustc_llvm;
extern crate rustc_back;
extern crate serialize;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4702,7 +4702,7 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
}
ty_tup(ref tys) if tys.is_empty() => ::util::ppaux::ty_to_string(cx, ty),

ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
ty_enum(id, _) => format!("enum `{}`", item_path_str(cx, id)),
ty_uniq(_) => "box".to_string(),
ty_vec(_, Some(n)) => format!("array of {} elements", n),
ty_vec(_, None) => "slice".to_string(),
Expand All @@ -4714,7 +4714,7 @@ pub fn ty_sort_string<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> String {
format!("trait {}", item_path_str(cx, inner.principal_def_id()))
}
ty_struct(id, _) => {
format!("struct {}", item_path_str(cx, id))
format!("struct `{}`", item_path_str(cx, id))
}
ty_unboxed_closure(..) => "closure".to_string(),
ty_tup(_) => "tuple".to_string(),
Expand Down
55 changes: 54 additions & 1 deletion src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use metadata::filesearch;
use session::search_paths::PathKind;
use util::nodemap::NodeMap;

use regex::Regex;

use syntax::ast::NodeId;
use syntax::codemap::Span;
use syntax::diagnostic::{self, Emitter};
Expand Down Expand Up @@ -71,7 +73,58 @@ impl Session {
self.diagnostic().handler().fatal(msg)
}
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) {
self.diagnostic().span_err_with_code(sp, msg, code)
Expand Down
14 changes: 12 additions & 2 deletions src/test/compile-fail/array-not-vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@
// except according to those terms.

fn main() {
let _x: isize = [1is, 2, 3]; //~ ERROR expected isize, found array of 3 elements
let _x: isize = [1is, 2, 3];
//~^ ERROR mismatched types
//~| expected `isize`
//~| found `[isize; 3]`
//~| expected isize
//~| found array of 3 elements

let x: &[isize] = &[1, 2, 3];
let _y: &isize = x; //~ ERROR expected isize, found slice
let _y: &isize = x;
//~^ ERROR mismatched types
//~| expected `&isize`
//~| found `&[isize]`
//~| expected isize
//~| found slice
}
17 changes: 14 additions & 3 deletions src/test/compile-fail/associated-types-eq-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ fn foo1<I: Foo<A=Bar>>(x: I) {
}

fn foo2<I: Foo>(x: I) {
let _: Bar = x.boo(); //~ERROR mismatched types
let _: Bar = x.boo();
//~^ ERROR mismatched types
//~| expected `Bar`
//~| found `<I as Foo>::A`
//~| expected struct `Bar`
//~| found associated type
}


Expand All @@ -41,6 +46,12 @@ pub fn baz(x: &Foo<A=Bar>) {

pub fn main() {
let a = 42is;
foo1(a); //~ERROR expected usize, found struct Bar
baz(&a); //~ERROR expected usize, found struct Bar
foo1(a);
//~^ ERROR type mismatch resolving
//~| expected usize
//~| found struct `Bar`
baz(&a);
//~^ ERROR type mismatch resolving
//~| expected usize
//~| found struct `Bar`
}
10 changes: 8 additions & 2 deletions src/test/compile-fail/associated-types-path-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ pub fn f2<T: Foo>(a: T) -> T::A {

pub fn f1_int_int() {
f1(2is, 4is);
//~^ ERROR expected usize, found isize
//~^ ERROR type mismatch resolving
//~| expected usize
//~| found isize
}

pub fn f1_int_uint() {
Expand All @@ -46,7 +48,11 @@ pub fn f1_uint_int() {

pub fn f2_int() {
let _: isize = f2(2is);
//~^ ERROR expected `isize`, found `usize`
//~^ ERROR mismatched types
//~| expected `isize`
//~| found `usize`
//~| expected isize
//~| found usize
}

pub fn main() { }
7 changes: 5 additions & 2 deletions src/test/compile-fail/bad-const-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:expected `collections::string::String`, found `isize`

static i: String = 10is;
//~^ ERROR mismatched types
//~| expected `collections::string::String`
//~| found `isize`
//~| expected struct `collections::string::String`
//~| found isize
fn main() { println!("{}", i); }
8 changes: 5 additions & 3 deletions src/test/compile-fail/block-must-not-have-result-do.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:mismatched types: expected `()`, found `bool`

fn main() {
loop {
true
true //~ ERROR mismatched types
//~| expected ()
//~| found bool
//~| expected ()
//~| found bool
}
}
8 changes: 5 additions & 3 deletions src/test/compile-fail/block-must-not-have-result-res.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:mismatched types: expected `()`, found `bool`

struct r;

impl Drop for r {
fn drop(&mut self) {
true
true //~ ERROR mismatched types
//~| expected ()
//~| found bool
//~| expected ()
//~| found bool
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/test/compile-fail/block-must-not-have-result-while.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:mismatched types: expected `()`, found `bool`

fn main() {
while true {
true
true //~ ERROR mismatched types
//~| expected `()`
//~| found `bool`
//~| expected ()
//~| found bool
}
}
7 changes: 6 additions & 1 deletion src/test/compile-fail/coercion-slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@
// Tests that we forbid coercion from `[T; n]` to `&[T]`

fn main() {
let _: &[isize] = [0is]; //~ERROR: mismatched types: expected `&[isize]`, found `[isize; 1]`
let _: &[isize] = [0is];
//~^ ERROR mismatched types
//~| expected `&[isize]`
//~| found `[isize; 1]`
//~| expected &-ptr
//~| found array of 1 elements
}
12 changes: 10 additions & 2 deletions src/test/compile-fail/const-cast-different-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@

static a: &'static str = "foo";
static b: *const u8 = a as *const u8;
//~^ ERROR mismatched types: expected `*const u8`, found `&'static str`
//~^ ERROR mismatched types
//~| expected *const u8
//~| found &'static str
//~| expected u8
//~| found str
static c: *const u8 = &a as *const u8;
//~^ ERROR mismatched types: expected `*const u8`, found `&&'static str`
//~^ ERROR mismatched types
//~| expected *const u8
//~| found &&'static str
//~| expected u8
//~| found &-ptr

fn main() {
}
6 changes: 5 additions & 1 deletion src/test/compile-fail/cross-borrow-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ impl Trait for Foo {}

pub fn main() {
let x: Box<Trait> = box Foo;
let _y: &Trait = x; //~ ERROR mismatched types: expected `&Trait`, found `Box<Trait>`
let _y: &Trait = x; //~ ERROR mismatched types
//~| expected `&Trait`
//~| found `Box<Trait>`
//~| expected &-ptr
//~| found box
}

21 changes: 18 additions & 3 deletions src/test/compile-fail/destructure-trait-ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,22 @@ fn main() {
let box x = box 1is as Box<T>; //~ ERROR type `Box<T>` cannot be dereferenced

// n > m
let &&x = &1is as &T; //~ ERROR found &-ptr
let &&&x = &(&1is as &T); //~ ERROR found &-ptr
let box box x = box 1is as Box<T>; //~ ERROR found box
let &&x = &1is as &T;
//~^ ERROR mismatched types
//~| expected `T`
//~| found `&_`
//~| expected trait T
//~| found &-ptr
let &&&x = &(&1is as &T);
//~^ ERROR mismatched types
//~| expected `T`
//~| found `&_`
//~| expected trait T
//~| found &-ptr
let box box x = box 1is as Box<T>;
//~^ ERROR mismatched types
//~| expected `T`
//~| found `Box<_>`
//~| expected trait T
//~| found box
}
9 changes: 7 additions & 2 deletions src/test/compile-fail/dst-bad-assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ pub fn main() {
// Assignment.
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
let z: Box<ToBar> = box Bar1 {f: 36};
f5.ptr = Bar1 {f: 36}; //~ ERROR mismatched types: expected `ToBar`, found `Bar1`
//~^ ERROR the trait `core::marker::Sized` is not implemented for the type `ToBar`
f5.ptr = Bar1 {f: 36};
//~^ ERROR mismatched types
//~| expected `ToBar`
//~| found `Bar1`
//~| expected trait ToBar
//~| found struct `Bar1`
//~| ERROR the trait `core::marker::Sized` is not implemented for the type `ToBar`
}
6 changes: 5 additions & 1 deletion src/test/compile-fail/dst-bad-coerce1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ pub fn main() {
let f1 = Fat { ptr: [1, 2, 3] };
let f2: &Fat<[isize; 3]> = &f1;
let f3: &Fat<[usize]> = f2;
//~^ ERROR mismatched types: expected `&Fat<[usize]>`, found `&Fat<[isize; 3]>`
//~^ ERROR mismatched types
//~| expected `&Fat<[usize]>`
//~| found `&Fat<[isize; 3]>`
//~| expected usize
//~| found isize

// With a trait.
let f1 = Fat { ptr: Foo };
Expand Down
6 changes: 5 additions & 1 deletion src/test/compile-fail/dst-bad-coerce4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@ pub fn main() {
// With a vec of isizes.
let f1: &Fat<[isize]> = &Fat { ptr: [1, 2, 3] };
let f2: &Fat<[isize; 3]> = f1;
//~^ ERROR mismatched types: expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>`
//~^ ERROR mismatched types
//~| expected `&Fat<[isize; 3]>`
//~| found `&Fat<[isize]>`
//~| expected array of 3 elements
//~| found slice
}
10 changes: 8 additions & 2 deletions src/test/compile-fail/explicit-self-lifetime-mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ struct Foo<'a,'b> {

impl<'a,'b> Foo<'a,'b> {
fn bar(self: Foo<'b,'a>) {}
//~^ ERROR mismatched types: expected `Foo<'a, 'b>`, found `Foo<'b, 'a>`
//~^^ ERROR mismatched types: expected `Foo<'a, 'b>`, found `Foo<'b, 'a>`
//~^ ERROR mismatched types
//~| expected `Foo<'a, 'b>`
//~| found `Foo<'b, 'a>`
//~| lifetime mismatch
//~| ERROR mismatched types
//~| expected `Foo<'a, 'b>`
//~| found `Foo<'b, 'a>`
//~| lifetime mismatch
}

fn main() {}
Expand Down
Loading