1
Fork 0

On E0271 for a closure behind a binding, point at binding in call too

```
error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs: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`
```
This commit is contained in:
Esteban Küber 2024-10-25 23:23:15 +00:00
parent d3a148fe07
commit 03e9a38390
3 changed files with 64 additions and 0 deletions

View file

@ -1424,6 +1424,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// | ^^^^^ expected `Unit3`, found `Unit4` // | ^^^^^ expected `Unit3`, found `Unit4`
// | // |
diag.span_label(span, ""); diag.span_label(span, "");
if !span.overlaps(obligation.cause.span) {
// Point at the binding corresponding to the closure where it is used.
diag.span_label(obligation.cause.span, "");
}
} }
let secondary_span = (|| { let secondary_span = (|| {

View file

@ -0,0 +1,25 @@
use std::error::Error;
use std::process::exit;
fn foo<F>(f: F) -> ()
where
F: FnOnce() -> Result<(), Box<dyn Error>>,
{
f().or_else(|e| -> ! { //~ ERROR to be a closure that returns
eprintln!("{:?}", e);
exit(1)
});
}
fn bar<F>(f: F) -> ()
where
F: FnOnce() -> Result<(), Box<dyn Error>>,
{
let c = |e| -> ! { //~ ERROR to be a closure that returns
eprintln!("{:?}", e);
exit(1)
};
f().or_else(c);
}
fn main() {}

View file

@ -0,0 +1,35 @@
error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:8:17}` to be a closure that returns `Result<(), _>`, but it returns `!`
--> $DIR/return-type-doesnt-match-bound.rs:8:24
|
LL | f().or_else(|e| -> ! {
| ------- -------^
| | |
| | expected `Result<(), _>`, found `!`
| 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`
--> $SRC_DIR/core/src/result.rs:LL:COL
error[E0271]: expected `{closure@return-type-doesnt-match-bound.rs:18:13}` to be a closure that returns `Result<(), _>`, but it returns `!`
--> $DIR/return-type-doesnt-match-bound.rs:18:20
|
LL | let c = |e| -> ! {
| -------^
| |
| expected `Result<(), _>`, found `!`
...
LL | 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`
--> $SRC_DIR/core/src/result.rs:LL:COL
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0271`.