Change:
Currently E277's message is confusing and seemingly ambiguous when it occurs on a try () expression (this may not be limited to E277, it's just the one I noticed). For example, in : The problem is that 's error type is while 's error type is . In this case the error isn't too confusing, but if the try is in a chained expression () and you're a noob it isn't clear why it wants implemented on . It doesn't necessarily even require a whole fix suggestion, all it would take is making the error only highlight the , as the issue is actually occuring when unwrapping the result. Thanks!

Discussion:
Symbol::intern("try_trait") ].into()), ); <ins> let try_span = self.sess.source_map().end_point(e.span); let try_span = self.mark_span_with_reason( CompilerDesugaringKind::QuestionMark, try_span, Some(vec![ Symbol::intern("try_trait") ].into()), ); </ins> // `Try::into_result(<expr>)` let discr = {

//              return Try::from_error(From::from(err)),` let err_arm = { let err_ident = self.str_to_ident("err"); <del> let (err_local, err_local_nid) = self.pat_ident(e.span, err_ident); </del> <ins> let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident); </ins> let from_expr = { let path = &["convert", "From", "from"]; let from = P(self.expr_std_path( <del> e.span, path, None, ThinVec::new())); let err_expr = self.expr_ident(e.span, err_ident, err_local_nid); </del> <ins> try_span, path, None, ThinVec::new())); let err_expr = self.expr_ident(try_span, err_ident, err_local_nid); </ins> <del> self.expr_call(e.span, from, hir_vec![err_expr]) </del> <ins> self.expr_call(try_span, from, hir_vec![err_expr]) </ins> }; let from_err_expr = self.wrap_in_try_constructor("from_error", from_expr, unstable_span);

let ret_expr = if let Some(catch_node) = catch_scope { let target_id = Ok(self.lower_node_id(catch_node).hir_id); P(self.expr( <del> e.span, </del> <ins> try_span, </ins> hir::ExprKind::Break( hir::Destination { label: None,

thin_attrs, )) } else { <del> P(self.expr(e.span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs)) </del> <ins> P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs)) </ins> }; <del> let err_pat = self.pat_err(e.span, err_local); </del> <ins> let err_pat = self.pat_err(try_span, err_local); </ins> self.arm(hir_vec![err_pat], ret_expr) };

let OnUnimplementedNote { message, label, note } = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); <ins> 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 }; </ins> let mut err = struct_span_err!( self.tcx.sess,

<del> error[E0277]: the trait bound `(): std::convert::From<{integer}>` is not satisfied --> $DIR/issue-32709.rs:4:5 </del> <ins> error[E0277]: `?` couldn't convert the error to `()` --> $DIR/issue-32709.rs:4:11 </ins> | LL |     Err(5)?; <del> |     ^^^^^^^ the trait `std::convert::From<{integer}>` is not implemented for `()` </del> <ins> |           ^ the trait `std::convert::From<{integer}>` is not implemented for `()` </ins> | = note: required by `std::convert::From::from`

pub fn main() { let res: Result<u32, i32> = try { <del> Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied </del> <ins> Err("")?; //~ ERROR `?` couldn't convert the error </ins> 5 };

<del> error[E0277]: the trait bound `i32: std::convert::From<&str>` is not satisfied --> $DIR/try-block-bad-type.rs:7:9 </del> <ins> error[E0277]: `?` couldn't convert the error to `i32` --> $DIR/try-block-bad-type.rs:7:16 </ins> | LL |         Err("")?; <del> |         ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32` </del> <ins> |                ^ the trait `std::convert::From<&str>` is not implemented for `i32` </ins> | = help: the following implementations were found: <i32 as std::convert::From<bool>>

fn foo() -> Result<u32, ()> { let x: Option<u32> = None; <del> x?; //~ the trait bound </del> <ins> x?; //~ ERROR `?` couldn't convert the error </ins> Ok(22) } fn bar() -> u32 { let x: Option<u32> = None; <del> x?; //~ the `?` operator </del> <ins> x?; //~ ERROR the `?` operator </ins> 22 }

<del> error[E0277]: the trait bound `(): std::convert::From<std::option::NoneError>` is not satisfied --> $DIR/try-on-option.rs:7:5 </del> <ins> error[E0277]: `?` couldn't convert the error to `()` --> $DIR/try-on-option.rs:7:6 </ins> | LL |     x?; <del> |     ^^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()` </del> <ins> |      ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()` </ins> | = note: required by `std::convert::From::from`