From 1e99b2ec9dc60dc01a413118051d273ed7688c7e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Esteban=20K=C3=BCber?= Date: Wed, 17 Apr 2019 19:50:50 -0700 Subject: [PATCH] Give custom error for E0277 on `?` error case --- src/librustc/traits/error_reporting.rs | 12 ++++++++++++ src/test/ui/issues/issue-32709.stderr | 2 +- src/test/ui/try-block/try-block-bad-type.rs | 2 +- src/test/ui/try-block/try-block-bad-type.stderr | 2 +- src/test/ui/try-on-option.rs | 4 ++-- src/test/ui/try-on-option.stderr | 2 +- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5b5a7cc9ed8..14c81a806c2 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -638,6 +638,18 @@ pub fn report_selection_error( let OnUnimplementedNote { message, label, note } = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); + let is_try = self.tcx.sess.source_map().span_to_snippet(span) + .map(|s| &s == "?") + .unwrap_or(false); + let is_from = format!("{}", trait_ref).starts_with("std::convert::From<"); + let message = if is_try && is_from { + Some(format!( + "`?` couldn't convert the error to `{}`", + trait_ref.self_ty(), + )) + } else { + message + }; let mut err = struct_span_err!( self.tcx.sess, diff --git a/src/test/ui/issues/issue-32709.stderr b/src/test/ui/issues/issue-32709.stderr index 4a37e0a2e52..84cca5b20af 100644 --- a/src/test/ui/issues/issue-32709.stderr +++ b/src/test/ui/issues/issue-32709.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): std::convert::From<{integer}>` is not satisfied +error[E0277]: `?` couldn't convert the error to `()` --> $DIR/issue-32709.rs:4:11 | LL | Err(5)?; diff --git a/src/test/ui/try-block/try-block-bad-type.rs b/src/test/ui/try-block/try-block-bad-type.rs index 0e297dd8ff1..4dfc8e6a2fc 100644 --- a/src/test/ui/try-block/try-block-bad-type.rs +++ b/src/test/ui/try-block/try-block-bad-type.rs @@ -4,7 +4,7 @@ pub fn main() { let res: Result = try { - Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied + Err("")?; //~ ERROR `?` couldn't convert the error 5 }; diff --git a/src/test/ui/try-block/try-block-bad-type.stderr b/src/test/ui/try-block/try-block-bad-type.stderr index a39c8cfba12..13593c4e8e7 100644 --- a/src/test/ui/try-block/try-block-bad-type.stderr +++ b/src/test/ui/try-block/try-block-bad-type.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `i32: std::convert::From<&str>` is not satisfied +error[E0277]: `?` couldn't convert the error to `i32` --> $DIR/try-block-bad-type.rs:7:16 | LL | Err("")?; diff --git a/src/test/ui/try-on-option.rs b/src/test/ui/try-on-option.rs index 9c8e8b33ad6..5d94cee8e37 100644 --- a/src/test/ui/try-on-option.rs +++ b/src/test/ui/try-on-option.rs @@ -4,12 +4,12 @@ fn main() {} fn foo() -> Result { let x: Option = None; - x?; //~ the trait bound + x?; //~ ERROR `?` couldn't convert the error Ok(22) } fn bar() -> u32 { let x: Option = None; - x?; //~ the `?` operator + x?; //~ ERROR the `?` operator 22 } diff --git a/src/test/ui/try-on-option.stderr b/src/test/ui/try-on-option.stderr index 3e081d03766..4465fbe14b7 100644 --- a/src/test/ui/try-on-option.stderr +++ b/src/test/ui/try-on-option.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `(): std::convert::From` is not satisfied +error[E0277]: `?` couldn't convert the error to `()` --> $DIR/try-on-option.rs:7:6 | LL | x?; -- 2.44.0