Skip to content

Commit

Permalink
Rollup merge of rust-lang#84244 - ABouttefeux:closure-return-conflict…
Browse files Browse the repository at this point in the history
…-suggest, r=estebank

fix incomplete diagnostic notes when closure returns conflicting for genric type

fixes rust-lang#84128
Correctly report the span on for conflicting return type in closures
  • Loading branch information
Joshua Nelson committed Apr 16, 2021
2 parents 1d83b1b + af90cac commit 0946b64
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
22 changes: 0 additions & 22 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
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
}

Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_missing_parentheses(err, expr);
self.note_need_for_fn_pointer(err, 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
Expand Down Expand Up @@ -1061,4 +1062,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => 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 changes: 16 additions & 0 deletions src/test/ui/closures/issue-84128.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 15 additions & 0 deletions src/test/ui/closures/issue-84128.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 0946b64

Please sign in to comment.