diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-10-25 23:23:15 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-01-30 18:38:41 +0000 |
| commit | 03e9a383906ca85e264f056f490c091fdef30a90 (patch) | |
| tree | bc72cc6ff320fc60f1c7db960a326f4d838555cd | |
| parent | d3a148fe07bf2bcab0d262463f0f892f555e0aa6 (diff) | |
| download | rust-03e9a383906ca85e264f056f490c091fdef30a90.tar.gz rust-03e9a383906ca85e264f056f490c091fdef30a90.zip | |
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`
```
3 files changed, 64 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 24615dfdc56..78f6cd9e656 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1424,6 +1424,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // | ^^^^^ expected `Unit3`, found `Unit4` // | 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 = (|| { diff --git a/tests/ui/closures/return-type-doesnt-match-bound.rs b/tests/ui/closures/return-type-doesnt-match-bound.rs new file mode 100644 index 00000000000..f9098d0cb5c --- /dev/null +++ b/tests/ui/closures/return-type-doesnt-match-bound.rs @@ -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() {} diff --git a/tests/ui/closures/return-type-doesnt-match-bound.stderr b/tests/ui/closures/return-type-doesnt-match-bound.stderr new file mode 100644 index 00000000000..c6aad2054f5 --- /dev/null +++ b/tests/ui/closures/return-type-doesnt-match-bound.stderr @@ -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`. |
