Auto merge of #84244 - ABouttefeux:closure-return-conflict-suggest, r=estebank
fix incomplete diagnostic notes when closure returns conflicting for genric type fixes #84128 Correctly report the span on for conflicting return type in closures
This commit is contained in:
commit
080d30235f
4 changed files with 60 additions and 22 deletions
|
@ -1492,28 +1492,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
|
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
|
||||||
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
|
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sp) = fcx.ret_coercion_span.get() {
|
|
||||||
// If the closure has an explicit return type annotation,
|
|
||||||
// then a type error may occur at the first return expression we
|
|
||||||
// see in the closure (if it conflicts with the declared
|
|
||||||
// return type). Skip adding a note in this case, since it
|
|
||||||
// would be incorrect.
|
|
||||||
if !err.span.primary_spans().iter().any(|&span| span == sp) {
|
|
||||||
let hir = fcx.tcx.hir();
|
|
||||||
let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id));
|
|
||||||
if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) {
|
|
||||||
err.span_note(
|
|
||||||
sp,
|
|
||||||
&format!(
|
|
||||||
"return type inferred to be `{}` here",
|
|
||||||
fcx.resolve_vars_if_possible(expected)
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.suggest_missing_parentheses(err, expr);
|
self.suggest_missing_parentheses(err, expr);
|
||||||
self.note_need_for_fn_pointer(err, expected, expr_ty);
|
self.note_need_for_fn_pointer(err, expected, expr_ty);
|
||||||
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
|
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
|
||||||
|
self.report_closure_infered_return_type(err, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Requires that the two types unify, and prints an error message if
|
// Requires that the two types unify, and prints an error message if
|
||||||
|
@ -1061,4 +1062,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report the type inferred by the return statement.
|
||||||
|
fn report_closure_infered_return_type(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
expected: Ty<'tcx>,
|
||||||
|
) {
|
||||||
|
if let Some(sp) = self.ret_coercion_span.get() {
|
||||||
|
// If the closure has an explicit return type annotation,
|
||||||
|
// then a type error may occur at the first return expression we
|
||||||
|
// see in the closure (if it conflicts with the declared
|
||||||
|
// return type). Skip adding a note in this case, since it
|
||||||
|
// would be incorrect.
|
||||||
|
if !err.span.primary_spans().iter().any(|&span| span == sp) {
|
||||||
|
let hir = self.tcx.hir();
|
||||||
|
let body_owner = hir.body_owned_by(hir.enclosing_body_owner(self.body_id));
|
||||||
|
if self.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) {
|
||||||
|
err.span_note(
|
||||||
|
sp,
|
||||||
|
&format!(
|
||||||
|
"return type inferred to be `{}` here",
|
||||||
|
self.resolve_vars_if_possible(expected)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/test/ui/closures/issue-84128.rs
Normal file
16
src/test/ui/closures/issue-84128.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// test for issue 84128
|
||||||
|
// missing suggestion for similar ADT type with diffetent generic paramenter
|
||||||
|
// on closure ReturnNoExpression
|
||||||
|
|
||||||
|
struct Foo<T>(T);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|| {
|
||||||
|
if false {
|
||||||
|
return Foo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Foo(())
|
||||||
|
//~^ ERROR mismatched types [E0308]
|
||||||
|
};
|
||||||
|
}
|
15
src/test/ui/closures/issue-84128.stderr
Normal file
15
src/test/ui/closures/issue-84128.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-84128.rs:13:13
|
||||||
|
|
|
||||||
|
LL | Foo(())
|
||||||
|
| ^^ expected integer, found `()`
|
||||||
|
|
|
||||||
|
note: return type inferred to be `{integer}` here
|
||||||
|
--> $DIR/issue-84128.rs:10:20
|
||||||
|
|
|
||||||
|
LL | return Foo(0);
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue