From 36faafee8d836983754005df4e6b7709829aa5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 25 Nov 2017 06:00:26 -0800 Subject: [PATCH] Use suggestions instead of notes ref mismatches On type mismatch errors, use a suggestion when encountering minimal differences in type differences due to refs, instead of a note. --- src/librustc_typeck/check/demand.rs | 34 +++++++++++-------- src/test/compile-fail/issue-13058.rs | 2 +- src/test/ui/deref-suggestion.stderr | 18 ++++++---- src/test/ui/span/coerce-suggestions.rs | 2 +- src/test/ui/span/coerce-suggestions.stderr | 12 ++++--- src/test/ui/str-lit-type-mismatch.stderr | 18 ++++++---- .../ui/suggestions/str-array-assignment.rs | 2 +- .../suggestions/str-array-assignment.stderr | 6 ++-- 8 files changed, 58 insertions(+), 36 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 08cf6d3a59ec5..4724a0fa51b97 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -134,10 +134,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - if let Some(suggestion) = self.check_ref(expr, - checked_ty, - expected) { - err.help(&suggestion); + if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) { + err.span_suggestion(expr.span, msg, suggestion); } else { let mode = probe::Mode::MethodCall; let suggestions = self.probe_for_return_type(syntax_pos::DUMMY_SP, @@ -214,7 +212,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) - -> Option { + -> Option<(&'static str, String)> { match (&expected.sty, &checked_ty.sty) { (&ty::TyRef(_, exp), &ty::TyRef(_, check)) => match (&exp.ty.sty, &check.ty.sty) { (&ty::TyStr, &ty::TyArray(arr, _)) | @@ -222,7 +220,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let hir::ExprLit(_) = expr.node { let sp = self.sess().codemap().call_span_if_macro(expr.span); if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { - return Some(format!("try `{}`", &src[1..])); + return Some(("consider removing the leading `b`", + src[1..].to_string())); } } None @@ -232,7 +231,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let hir::ExprLit(_) = expr.node { let sp = self.sess().codemap().call_span_if_macro(expr.span); if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { - return Some(format!("try `b{}`", src)); + return Some(("consider adding a leading `b`", + format!("b{}", src))); } } None @@ -260,12 +260,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Use the callsite's span if this is a macro call. #41858 let sp = self.sess().codemap().call_span_if_macro(expr.span); if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { - return Some(format!("try with `{}{}`", - match mutability.mutbl { - hir::Mutability::MutMutable => "&mut ", - hir::Mutability::MutImmutable => "&", - }, - &src)); + return Some(match mutability.mutbl { + hir::Mutability::MutMutable => { + ("consider mutably borrowing here", format!("&mut {}", src)) + } + hir::Mutability::MutImmutable => { + ("consider borrowing here", format!("&{}", src)) + } + }); } } None @@ -284,7 +286,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Maybe remove `&`? hir::ExprAddrOf(_, ref expr) => { if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(expr.span) { - return Some(format!("try with `{}`", code)); + return Some(("consider removing the borrow", + code)); } } @@ -295,7 +298,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr.span) { let sp = self.sess().codemap().call_span_if_macro(expr.span); if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(sp) { - return Some(format!("try with `*{}`", code)); + return Some(("consider dereferencing the borrow", + format!("*{}", code))); } } }, diff --git a/src/test/compile-fail/issue-13058.rs b/src/test/compile-fail/issue-13058.rs index 590f8073a1a0d..27b23f083217d 100644 --- a/src/test/compile-fail/issue-13058.rs +++ b/src/test/compile-fail/issue-13058.rs @@ -35,5 +35,5 @@ fn check<'r, I: Iterator, T: Itble<'r, usize, I>>(cont: &T) -> bool fn main() { check((3, 5)); //~^ ERROR mismatched types -//~| HELP try with `&(3, 5)` +//~| HELP consider borrowing here } diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 6c418cf4bfbed..98ec3d9693fb8 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -17,31 +17,37 @@ error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:23:10 | 23 | foo3(u); //~ ERROR mismatched types - | ^ expected u32, found &u32 + | ^ + | | + | expected u32, found &u32 + | help: consider dereferencing the borrow: `*u` | = note: expected type `u32` found type `&u32` - = help: try with `*u` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:30:9 | 30 | foo(&"aaa".to_owned()); //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found reference + | ^^^^^^^^^^^^^^^^^ + | | + | expected struct `std::string::String`, found reference + | help: consider removing the borrow: `"aaa".to_owned()` | = note: expected type `std::string::String` found type `&std::string::String` - = help: try with `"aaa".to_owned()` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:31:9 | 31 | foo(&mut "aaa".to_owned()); //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found mutable reference + | ^^^^^^^^^^^^^^^^^^^^^ + | | + | expected struct `std::string::String`, found mutable reference + | help: consider removing the borrow: `"aaa".to_owned()` | = note: expected type `std::string::String` found type `&mut std::string::String` - = help: try with `"aaa".to_owned()` error[E0308]: mismatched types --> $DIR/deref-suggestion.rs:12:20 diff --git a/src/test/ui/span/coerce-suggestions.rs b/src/test/ui/span/coerce-suggestions.rs index a1a250b0e9ad2..0a3e18043fe45 100644 --- a/src/test/ui/span/coerce-suggestions.rs +++ b/src/test/ui/span/coerce-suggestions.rs @@ -23,7 +23,7 @@ fn main() { //~^ ERROR E0308 //~| NOTE expected &str, found struct `std::string::String` //~| NOTE expected type `&str` - //~| HELP try with `&String::new()` + //~| HELP consider borrowing here let y = String::new(); test(&y); //~^ ERROR E0308 diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 98ea34fd992c8..604b38bef6cc4 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -14,11 +14,13 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:22:19 | 22 | let x: &str = String::new(); - | ^^^^^^^^^^^^^ expected &str, found struct `std::string::String` + | ^^^^^^^^^^^^^ + | | + | expected &str, found struct `std::string::String` + | help: consider borrowing here: `&String::new()` | = note: expected type `&str` found type `std::string::String` - = help: try with `&String::new()` error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:28:10 @@ -48,11 +50,13 @@ error[E0308]: mismatched types --> $DIR/coerce-suggestions.rs:42:9 | 42 | s = format!("foo"); - | ^^^^^^^^^^^^^^ expected mutable reference, found struct `std::string::String` + | ^^^^^^^^^^^^^^ + | | + | expected mutable reference, found struct `std::string::String` + | help: consider mutably borrowing here: `&mut format!("foo")` | = note: expected type `&mut std::string::String` found type `std::string::String` - = help: try with `&mut format!("foo")` = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/src/test/ui/str-lit-type-mismatch.stderr b/src/test/ui/str-lit-type-mismatch.stderr index bf7646d81eb1d..b232bf74666b1 100644 --- a/src/test/ui/str-lit-type-mismatch.stderr +++ b/src/test/ui/str-lit-type-mismatch.stderr @@ -2,31 +2,37 @@ error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:13:20 | 13 | let x: &[u8] = "foo"; //~ ERROR mismatched types - | ^^^^^ expected slice, found str + | ^^^^^ + | | + | expected slice, found str + | help: consider adding a leading `b`: `b"foo"` | = note: expected type `&[u8]` found type `&'static str` - = help: try `b"foo"` error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:14:23 | 14 | let y: &[u8; 4] = "baaa"; //~ ERROR mismatched types - | ^^^^^^ expected array of 4 elements, found str + | ^^^^^^ + | | + | expected array of 4 elements, found str + | help: consider adding a leading `b`: `b"baaa"` | = note: expected type `&[u8; 4]` found type `&'static str` - = help: try `b"baaa"` error[E0308]: mismatched types --> $DIR/str-lit-type-mismatch.rs:15:19 | 15 | let z: &str = b"foo"; //~ ERROR mismatched types - | ^^^^^^ expected str, found array of 3 elements + | ^^^^^^ + | | + | expected str, found array of 3 elements + | help: consider removing the leading `b`: `"foo"` | = note: expected type `&str` found type `&'static [u8; 3]` - = help: try `"foo"` error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/str-array-assignment.rs b/src/test/ui/suggestions/str-array-assignment.rs index 6c7f4852a4ae5..444684507d387 100644 --- a/src/test/ui/suggestions/str-array-assignment.rs +++ b/src/test/ui/suggestions/str-array-assignment.rs @@ -28,5 +28,5 @@ fn main() { //~ NOTE expected `()` because of default return type //~^ ERROR mismatched types //~| NOTE expected &str, found str //~| NOTE expected type - //~| HELP try with `&s[..2]` + //~| HELP consider borrowing here } diff --git a/src/test/ui/suggestions/str-array-assignment.stderr b/src/test/ui/suggestions/str-array-assignment.stderr index 14b744c2e469c..c65639805af6c 100644 --- a/src/test/ui/suggestions/str-array-assignment.stderr +++ b/src/test/ui/suggestions/str-array-assignment.stderr @@ -34,11 +34,13 @@ error[E0308]: mismatched types --> $DIR/str-array-assignment.rs:27:17 | 27 | let w: &str = s[..2]; - | ^^^^^^ expected &str, found str + | ^^^^^^ + | | + | expected &str, found str + | help: consider borrowing here: `&s[..2]` | = note: expected type `&str` found type `str` - = help: try with `&s[..2]` error: aborting due to 4 previous errors