Skip to content

Commit 03e9a38

Browse files
committed
On E0271 for a closure behind a binding, point at binding in call too
``` error[E0271]: expected `{[email protected]:18:13}` to be a closure that returns `Result<(), _>`, but it returns `!` --> tests/ui/closures/return-type-doesnt-match-bound.rs:18:20 | 18 | let c = |e| -> ! { //~ ERROR to be a closure that returns | -------^ | | | expected `Result<(), _>`, found `!` ... 22 | f().or_else(c); | ------- - | | | required by a bound introduced by this call | = note: expected enum `Result<(), _>` found type `!` note: required by a bound in `Result::<T, E>::or_else` --> /home/gh-estebank/rust/library/core/src/result.rs:1406:39 | 1406 | pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> { | ^^^^^^^^^^^^ required by this bound in `Result::<T, E>::or_else` ```
1 parent d3a148f commit 03e9a38

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
14241424
// | ^^^^^ expected `Unit3`, found `Unit4`
14251425
// |
14261426
diag.span_label(span, "");
1427+
if !span.overlaps(obligation.cause.span) {
1428+
// Point at the binding corresponding to the closure where it is used.
1429+
diag.span_label(obligation.cause.span, "");
1430+
}
14271431
}
14281432

14291433
let secondary_span = (|| {

Diff for: tests/ui/closures/return-type-doesnt-match-bound.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use std::error::Error;
2+
use std::process::exit;
3+
4+
fn foo<F>(f: F) -> ()
5+
where
6+
F: FnOnce() -> Result<(), Box<dyn Error>>,
7+
{
8+
f().or_else(|e| -> ! { //~ ERROR to be a closure that returns
9+
eprintln!("{:?}", e);
10+
exit(1)
11+
});
12+
}
13+
14+
fn bar<F>(f: F) -> ()
15+
where
16+
F: FnOnce() -> Result<(), Box<dyn Error>>,
17+
{
18+
let c = |e| -> ! { //~ ERROR to be a closure that returns
19+
eprintln!("{:?}", e);
20+
exit(1)
21+
};
22+
f().or_else(c);
23+
}
24+
25+
fn main() {}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0271]: expected `{[email protected]:8:17}` to be a closure that returns `Result<(), _>`, but it returns `!`
2+
--> $DIR/return-type-doesnt-match-bound.rs:8:24
3+
|
4+
LL | f().or_else(|e| -> ! {
5+
| ------- -------^
6+
| | |
7+
| | expected `Result<(), _>`, found `!`
8+
| required by a bound introduced by this call
9+
|
10+
= note: expected enum `Result<(), _>`
11+
found type `!`
12+
note: required by a bound in `Result::<T, E>::or_else`
13+
--> $SRC_DIR/core/src/result.rs:LL:COL
14+
15+
error[E0271]: expected `{[email protected]:18:13}` to be a closure that returns `Result<(), _>`, but it returns `!`
16+
--> $DIR/return-type-doesnt-match-bound.rs:18:20
17+
|
18+
LL | let c = |e| -> ! {
19+
| -------^
20+
| |
21+
| expected `Result<(), _>`, found `!`
22+
...
23+
LL | f().or_else(c);
24+
| ------- -
25+
| |
26+
| required by a bound introduced by this call
27+
|
28+
= note: expected enum `Result<(), _>`
29+
found type `!`
30+
note: required by a bound in `Result::<T, E>::or_else`
31+
--> $SRC_DIR/core/src/result.rs:LL:COL
32+
33+
error: aborting due to 2 previous errors
34+
35+
For more information about this error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)