diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 36222e172b8d6..819717628d62d 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -977,7 +977,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { if let Categorization::Local(local_id) = err.cmt.cat { let span = self.tcx.map.span(local_id); if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) { - if snippet != "self" { + if snippet.starts_with("ref ") { + db.span_label(span, + &format!("use `{}` here to make mutable", + snippet.replace("ref ", "ref mut "))); + } else if snippet != "self" { db.span_label(span, &format!("use `mut {}` here to make mutable", snippet)); } diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs index 7c9985d7d2331..6b15aa4f92c57 100644 --- a/src/libsyntax/errors/emitter.rs +++ b/src/libsyntax/errors/emitter.rs @@ -682,6 +682,7 @@ mod test { println!("r#\"\n{}\"#", str); assert_eq!(str, &r#" --> dummy.txt:11:1 + |> 11 |> e-lä-vän |> ^ "#[1..]); @@ -746,6 +747,7 @@ mod test { let expect_start = &r#" --> dummy.txt:1:6 + |> 1 |> _____aaaaaa____bbbbbb__cccccdd_ |> ^^^^^^ ^^^^^^ ^^^^^^^ "#[1..]; @@ -818,6 +820,7 @@ mod test { let expect0 = &r#" --> dummy.txt:5:1 + |> 5 |> ccccc |> ^ ... @@ -830,6 +833,7 @@ mod test { let expect = &r#" --> dummy.txt:1:1 + |> 1 |> aaaaa |> ^ ... diff --git a/src/libsyntax/errors/snippet/mod.rs b/src/libsyntax/errors/snippet/mod.rs index 188e676e7dff6..2a43a14ddf873 100644 --- a/src/libsyntax/errors/snippet/mod.rs +++ b/src/libsyntax/errors/snippet/mod.rs @@ -478,6 +478,13 @@ impl FileInfo { }], kind: RenderedLineKind::PrimaryFileName, }); + output.push(RenderedLine { + text: vec![StyledString { + text: "".to_string(), + style: Style::FileNameStyle, + }], + kind: RenderedLineKind::Annotations, + }); } None => { output.push(RenderedLine { @@ -487,6 +494,13 @@ impl FileInfo { }], kind: RenderedLineKind::OtherFileName, }); + output.push(RenderedLine { + text: vec![StyledString { + text: "".to_string(), + style: Style::FileNameStyle, + }], + kind: RenderedLineKind::Annotations, + }); } } } diff --git a/src/libsyntax/errors/snippet/test.rs b/src/libsyntax/errors/snippet/test.rs index 62ce3fa9dd5e9..51fe4572dbc63 100644 --- a/src/libsyntax/errors/snippet/test.rs +++ b/src/libsyntax/errors/snippet/test.rs @@ -98,6 +98,7 @@ fn foo() { let text = make_string(&lines); assert_eq!(&text[..], &" --> foo.rs:3:2 + |> 3 |> \tbar; |> \t^^^ "[1..]); @@ -130,6 +131,7 @@ fn foo() { println!("text=\n{}", text); assert_eq!(&text[..], &r#" ::: foo.rs + |> 3 |> vec.push(vec.pop().unwrap()); |> --- --- - previous borrow ends here |> | | @@ -199,12 +201,14 @@ fn bar() { // Note that the `|>` remain aligned across both files: assert_eq!(&text[..], &r#" --> foo.rs:3:14 + |> 3 |> vec.push(vec.pop().unwrap()); |> --- ^^^ - c |> | | |> | b |> a ::: bar.rs + |> 17 |> vec.push(); |> --- - f |> | @@ -249,6 +253,7 @@ fn foo() { println!("text=\n{}", text); assert_eq!(&text[..], &r#" ::: foo.rs + |> 3 |> let name = find_id(&data, 22).unwrap(); |> ---- immutable borrow begins here ... @@ -288,6 +293,7 @@ fn foo() { println!("text=r#\"\n{}\".trim_left()", text); assert_eq!(&text[..], &r#" ::: foo.rs + |> 3 |> vec.push(vec.pop().unwrap()); |> -------- ------ D |> || @@ -324,6 +330,7 @@ fn foo() { println!("text=r#\"\n{}\".trim_left()", text); assert_eq!(&text[..], &r#" ::: foo.rs + |> 3 |> vec.push(vec.pop().unwrap()); |> --- --- - previous borrow ends here |> | | @@ -362,6 +369,7 @@ fn foo() { println!("text=r#\"\n{}\".trim_left()", text); assert_eq!(&text[..], &r#" ::: foo.rs + |> 4 |> let mut vec2 = vec; |> --- `vec` moved here because it has type `collections::vec::Vec` ... @@ -398,6 +406,7 @@ fn foo() { println!("text=&r#\"\n{}\n\"#[1..]", text); assert_eq!(text, &r#" ::: foo.rs + |> 3 |> let mut vec = vec![0, 1, 2]; |> --- --- 4 |> let mut vec2 = vec; @@ -429,6 +438,7 @@ impl SomeTrait for () { println!("r#\"\n{}\"", text); assert_eq!(text, &r#" ::: foo.rs + |> 3 |> fn foo(x: u32) { |> - "#[1..]); @@ -458,6 +468,7 @@ fn span_overlap_label() { println!("r#\"\n{}\"", text); assert_eq!(text, &r#" ::: foo.rs + |> 2 |> fn foo(x: u32) { |> -------------- |> | | @@ -492,6 +503,7 @@ fn span_overlap_label2() { println!("r#\"\n{}\"", text); assert_eq!(text, &r#" ::: foo.rs + |> 2 |> fn foo(x: u32) { |> -------------- |> | | @@ -537,6 +549,7 @@ fn span_overlap_label3() { println!("r#\"\n{}\"", text); assert_eq!(text, &r#" ::: foo.rs + |> 3 |> let closure = || { |> - foo 4 |> inner @@ -577,6 +590,7 @@ fn main() { println!("r#\"\n{}\"", text); assert_eq!(text, &r#" --> foo.rs:11:2 + |> 11 |> } |> - "#[1..]); diff --git a/src/test/compile-fail/issue-33819.rs b/src/test/compile-fail/issue-33819.rs new file mode 100644 index 0000000000000..9c9677c1e9863 --- /dev/null +++ b/src/test/compile-fail/issue-33819.rs @@ -0,0 +1,18 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +fn main() { + let mut op = Some(2); + match op { + Some(ref v) => { let a = &mut v; }, + //~^ ERROR:cannot borrow immutable + //~| use `ref mut v` here to make mutable + None => {}, + } +} diff --git a/src/test/run-make/unicode-input/span_length.rs b/src/test/run-make/unicode-input/span_length.rs index 3963d20df8873..da8769e616c3f 100644 --- a/src/test/run-make/unicode-input/span_length.rs +++ b/src/test/run-make/unicode-input/span_length.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rand, core)] +#![feature(rand)] use std::fs::File; use std::io::prelude::*; @@ -18,6 +18,11 @@ use std::process::Command; use std::__rand::{thread_rng, Rng}; use std::{char, env}; +pub fn check_old_skool() -> bool { + use std::env; + env::var("RUST_NEW_ERROR_FORMAT").is_err() +} + // creates a file with `fn main() { }` and checks the // compiler emits a span of the appropriate length (for the // "unresolved name" message); currently just using the number of code @@ -65,10 +70,17 @@ fn main() { let err = String::from_utf8_lossy(&result.stderr); - // the span should end the line (e.g no extra ~'s) - let expected_span = format!("^{}\n", repeat("~").take(n - 1) - .collect::()); - assert!(err.contains(&expected_span)); + if check_old_skool() { + // the span should end the line (e.g no extra ~'s) + let expected_span = format!("^{}\n", repeat("~").take(n - 1) + .collect::()); + assert!(err.contains(&expected_span)); + } else { + // the span should end the line (e.g no extra ~'s) + let expected_span = format!("^{}\n", repeat("^").take(n - 1) + .collect::()); + assert!(err.contains(&expected_span)); + } } // Test multi-column characters and tabs @@ -77,9 +89,6 @@ fn main() { r#"extern "路濫狼á́́" fn foo() {{}} extern "路濫狼á́" fn bar() {{}}"#); } - // Extra characters. Every line is preceded by `filename:lineno ` - let offset = main_file.to_str().unwrap().len() + 3; - let result = Command::new("sh") .arg("-c") .arg(format!("{} {}", @@ -91,17 +100,31 @@ fn main() { // Test both the length of the snake and the leading spaces up to it - // First snake is 8 ~s long, with 7 preceding spaces (excluding file name/line offset) - let expected_span = format!("\n{}^{}\n", - repeat(" ").take(offset + 7).collect::(), - repeat("~").take(8).collect::()); - assert!(err.contains(&expected_span)); - // Second snake is only 7 ~s long, with 36 preceding spaces, - // because rustc counts chars() now rather than width(). This - // is because width() functions are to be removed from - // librustc_unicode - let expected_span = format!("\n{}^{}\n", - repeat(" ").take(offset + 36).collect::(), - repeat("~").take(7).collect::()); - assert!(err.contains(&expected_span)); + if check_old_skool() { + // Extra characters. Every line is preceded by `filename:lineno ` + let offset = main_file.to_str().unwrap().len() + 3; + + // First snake is 8 ~s long, with 7 preceding spaces (excluding file name/line offset) + let expected_span = format!("\n{}^{}\n", + repeat(" ").take(offset + 7).collect::(), + repeat("~").take(8).collect::()); + assert!(err.contains(&expected_span)); + // Second snake is only 7 ~s long, with 36 preceding spaces, + // because rustc counts chars() now rather than width(). This + // is because width() functions are to be removed from + // librustc_unicode + let expected_span = format!("\n{}^{}\n", + repeat(" ").take(offset + 36).collect::(), + repeat("~").take(7).collect::()); + assert!(err.contains(&expected_span)); + } else { + let expected_span = format!("\n |>{}{}\n", + repeat(" ").take(8).collect::(), + repeat("^").take(9).collect::()); + assert!(err.contains(&expected_span)); + let expected_span = format!("\n |>{}{}\n", + repeat(" ").take(37).collect::(), + repeat("^").take(8).collect::()); + assert!(err.contains(&expected_span)); + } } diff --git a/src/test/compile-fail/issue-26480.rs b/src/test/ui/mismatched_types/issue-26480.rs similarity index 72% rename from src/test/compile-fail/issue-26480.rs rename to src/test/ui/mismatched_types/issue-26480.rs index 634a4014e1189..96db31f4b116f 100644 --- a/src/test/compile-fail/issue-26480.rs +++ b/src/test/ui/mismatched_types/issue-26480.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// rustc-env:RUST_NEW_ERROR_FORMAT extern { fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64; } @@ -24,25 +25,16 @@ macro_rules! write { unsafe { write(stdout, $arr.as_ptr() as *const i8, $arr.len() * size_of($arr[0])); - //~^ ERROR mismatched types - //~| expected u64, found usize - //~| expected type - //~| found type } }} } macro_rules! cast { - ($x:expr) => ($x as ()) //~ ERROR non-scalar cast + ($x:expr) => ($x as ()) } fn main() { let hello = ['H', 'e', 'y']; write!(hello); - //~^ NOTE in this expansion of write! - //~| NOTE in this expansion of write! - //~| NOTE in this expansion of write! - cast!(2); - //~^ NOTE in this expansion of cast! } diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr new file mode 100644 index 0000000000000..c00594a59c115 --- /dev/null +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -0,0 +1,15 @@ +error: mismatched types [--explain E0308] + --> $DIR/issue-26480.rs:27:19 + |> +27 |> $arr.len() * size_of($arr[0])); + |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize +$DIR/issue-26480.rs:38:5: 38:19: note: in this expansion of write! (defined in $DIR/issue-26480.rs) + +error: non-scalar cast: `_` as `()` + --> $DIR/issue-26480.rs:33:19 + |> +33 |> ($x:expr) => ($x as ()) + |> ^^^^^^^^ +$DIR/issue-26480.rs:39:5: 39:14: note: in this expansion of cast! (defined in $DIR/issue-26480.rs) + +error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/main.stderr b/src/test/ui/mismatched_types/main.stderr index 98bc11752e0ed..1af332ee5bea7 100644 --- a/src/test/ui/mismatched_types/main.stderr +++ b/src/test/ui/mismatched_types/main.stderr @@ -1,5 +1,6 @@ error: mismatched types [--explain E0308] --> $DIR/main.rs:14:18 + |> 14 |> let x: u32 = ( |> ^ expected u32, found () note: expected type `u32`