Skip to content

Commit c6732f0

Browse files
authored
Rollup merge of rust-lang#60064 - estebank:issue-59980, r=varkor
Point at try `?` on errors affecting the err match arm of the desugared code Fix rust-lang#59980.
2 parents 7dc08c0 + 1e99b2e commit c6732f0

File tree

7 files changed

+39
-19
lines changed

7 files changed

+39
-19
lines changed

src/librustc/hir/lowering.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -4685,6 +4685,14 @@ impl<'a> LoweringContext<'a> {
46854685
Symbol::intern("try_trait")
46864686
].into()),
46874687
);
4688+
let try_span = self.sess.source_map().end_point(e.span);
4689+
let try_span = self.mark_span_with_reason(
4690+
CompilerDesugaringKind::QuestionMark,
4691+
try_span,
4692+
Some(vec![
4693+
Symbol::intern("try_trait")
4694+
].into()),
4695+
);
46884696

46894697
// `Try::into_result(<expr>)`
46904698
let discr = {
@@ -4729,14 +4737,14 @@ impl<'a> LoweringContext<'a> {
47294737
// return Try::from_error(From::from(err)),`
47304738
let err_arm = {
47314739
let err_ident = self.str_to_ident("err");
4732-
let (err_local, err_local_nid) = self.pat_ident(e.span, err_ident);
4740+
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
47334741
let from_expr = {
47344742
let path = &["convert", "From", "from"];
47354743
let from = P(self.expr_std_path(
4736-
e.span, path, None, ThinVec::new()));
4737-
let err_expr = self.expr_ident(e.span, err_ident, err_local_nid);
4744+
try_span, path, None, ThinVec::new()));
4745+
let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
47384746

4739-
self.expr_call(e.span, from, hir_vec![err_expr])
4747+
self.expr_call(try_span, from, hir_vec![err_expr])
47404748
};
47414749
let from_err_expr =
47424750
self.wrap_in_try_constructor("from_error", from_expr, unstable_span);
@@ -4745,7 +4753,7 @@ impl<'a> LoweringContext<'a> {
47454753
let ret_expr = if let Some(catch_node) = catch_scope {
47464754
let target_id = Ok(self.lower_node_id(catch_node).hir_id);
47474755
P(self.expr(
4748-
e.span,
4756+
try_span,
47494757
hir::ExprKind::Break(
47504758
hir::Destination {
47514759
label: None,
@@ -4756,10 +4764,10 @@ impl<'a> LoweringContext<'a> {
47564764
thin_attrs,
47574765
))
47584766
} else {
4759-
P(self.expr(e.span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
4767+
P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
47604768
};
47614769

4762-
let err_pat = self.pat_err(e.span, err_local);
4770+
let err_pat = self.pat_err(try_span, err_local);
47634771
self.arm(hir_vec![err_pat], ret_expr)
47644772
};
47654773

src/librustc/traits/error_reporting.rs

+12
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
638638
let OnUnimplementedNote { message, label, note }
639639
= self.on_unimplemented_note(trait_ref, obligation);
640640
let have_alt_message = message.is_some() || label.is_some();
641+
let is_try = self.tcx.sess.source_map().span_to_snippet(span)
642+
.map(|s| &s == "?")
643+
.unwrap_or(false);
644+
let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
645+
let message = if is_try && is_from {
646+
Some(format!(
647+
"`?` couldn't convert the error to `{}`",
648+
trait_ref.self_ty(),
649+
))
650+
} else {
651+
message
652+
};
641653

642654
let mut err = struct_span_err!(
643655
self.tcx.sess,

src/test/ui/issues/issue-32709.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `(): std::convert::From<{integer}>` is not satisfied
2-
--> $DIR/issue-32709.rs:4:5
1+
error[E0277]: `?` couldn't convert the error to `()`
2+
--> $DIR/issue-32709.rs:4:11
33
|
44
LL | Err(5)?;
5-
| ^^^^^^^ the trait `std::convert::From<{integer}>` is not implemented for `()`
5+
| ^ the trait `std::convert::From<{integer}>` is not implemented for `()`
66
|
77
= note: required by `std::convert::From::from`
88

src/test/ui/try-block/try-block-bad-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

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

src/test/ui/try-block/try-block-bad-type.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `i32: std::convert::From<&str>` is not satisfied
2-
--> $DIR/try-block-bad-type.rs:7:9
1+
error[E0277]: `?` couldn't convert the error to `i32`
2+
--> $DIR/try-block-bad-type.rs:7:16
33
|
44
LL | Err("")?;
5-
| ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32`
5+
| ^ the trait `std::convert::From<&str>` is not implemented for `i32`
66
|
77
= help: the following implementations were found:
88
<i32 as std::convert::From<bool>>

src/test/ui/try-on-option.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ fn main() {}
44

55
fn foo() -> Result<u32, ()> {
66
let x: Option<u32> = None;
7-
x?; //~ the trait bound
7+
x?; //~ ERROR `?` couldn't convert the error
88
Ok(22)
99
}
1010

1111
fn bar() -> u32 {
1212
let x: Option<u32> = None;
13-
x?; //~ the `?` operator
13+
x?; //~ ERROR the `?` operator
1414
22
1515
}

src/test/ui/try-on-option.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `(): std::convert::From<std::option::NoneError>` is not satisfied
2-
--> $DIR/try-on-option.rs:7:5
1+
error[E0277]: `?` couldn't convert the error to `()`
2+
--> $DIR/try-on-option.rs:7:6
33
|
44
LL | x?;
5-
| ^^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
5+
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
66
|
77
= note: required by `std::convert::From::from`
88

0 commit comments

Comments
 (0)